From 4ec5cdcd77aa1b6fc384197e1208061d62f16ba2 Mon Sep 17 00:00:00 2001
From: Patrick Lehmann <Patrick.Lehmann@plc2.de>
Date: Thu, 17 Jun 2021 13:11:32 +0200
Subject: Updates to the dom namespace in pyGHDL.

---
 pyGHDL/__init__.py                     |   6 +
 pyGHDL/dom/Common.py                   |  57 +++----
 pyGHDL/dom/DesignUnit.py               | 114 +++++++------
 pyGHDL/dom/Expression.py               | 287 ++++++++++++++++++++++++++++++++
 pyGHDL/dom/InterfaceItem.py            |  56 ++++---
 pyGHDL/dom/Literal.py                  |  55 ++++++
 pyGHDL/dom/Misc.py                     |  86 +++++-----
 pyGHDL/dom/Object.py                   |  72 ++++++++
 pyGHDL/dom/Range.py                    |  58 +++++++
 pyGHDL/dom/Symbol.py                   |  60 +++++++
 pyGHDL/dom/_Translate.py               | 208 +++++++++++++++++++++++
 pyGHDL/dom/_Utils.py                   |  38 +++++
 pyGHDL/dom/__init__.py                 |  20 +--
 pyGHDL/dom/formatting/__init__.py      |   0
 pyGHDL/dom/formatting/prettyprint.py   | 296 +++++++++++++++++++++++++++++++++
 pyGHDL/requirements.txt                |   2 +-
 testsuite/pyunit/SimpleEntity.vhdl     |   6 +-
 testsuite/pyunit/dom/SimpleEntity.py   |   2 +-
 testsuite/pyunit/libghdl/Initialize.py |   2 +-
 19 files changed, 1251 insertions(+), 174 deletions(-)
 create mode 100644 pyGHDL/dom/Expression.py
 create mode 100644 pyGHDL/dom/Literal.py
 create mode 100644 pyGHDL/dom/Object.py
 create mode 100644 pyGHDL/dom/Range.py
 create mode 100644 pyGHDL/dom/Symbol.py
 create mode 100644 pyGHDL/dom/_Translate.py
 create mode 100644 pyGHDL/dom/_Utils.py
 create mode 100644 pyGHDL/dom/formatting/__init__.py
 create mode 100644 pyGHDL/dom/formatting/prettyprint.py

diff --git a/pyGHDL/__init__.py b/pyGHDL/__init__.py
index 97ae27a03..0324bd15d 100644
--- a/pyGHDL/__init__.py
+++ b/pyGHDL/__init__.py
@@ -47,3 +47,9 @@ this is provided from a ``pyGHDL`` packages with four sub-packages:
 * ``pyGHDL.lsp`` - A `language server protocol <https://en.wikipedia.org/wiki/Language_Server_Protocol>`__ (LSP)
   written in Python. The implementation offers an HTTPS service that can be used e.g. by editors and IDEs supporting LSP.
 """
+from pydecor import export
+
+
+@export
+class GHDLBaseException(Exception):
+    pass
diff --git a/pyGHDL/dom/Common.py b/pyGHDL/dom/Common.py
index 646e074e5..88d0cdc8c 100644
--- a/pyGHDL/dom/Common.py
+++ b/pyGHDL/dom/Common.py
@@ -1,19 +1,19 @@
 # =============================================================================
-#                ____ _   _ ____  _          _
-#   _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
-#  | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
-#  | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
-#  | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
-#  |_|    |___/
+#               ____ _   _ ____  _          _
+#  _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
+# | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_|    |___/
 # =============================================================================
-#  Authors:
-#    Patrick Lehmann
+# Authors:
+#   Patrick Lehmann
 #
 # Package module:   DOM: Common classes for package pyGHDL.dom.
 #
 # License:
 # ============================================================================
-#  Copyright (C) 2019-2020 Tristan Gingold
+#  Copyright (C) 2019-2021 Tristan Gingold
 #
 #  This program is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
@@ -37,21 +37,14 @@
 """
 from pydecor import export
 
-from pyVHDLModel.VHDLModel import Mode
-
-from pyGHDL.libghdl import name_table
-from pyGHDL.libghdl.vhdl import nodes
+from pyGHDL                import GHDLBaseException
+from pyGHDL.libghdl        import LibGHDLException, errorout_memory
 
 __all__ = []
 
 
 @export
-class GHDLBaseException(Exception):
-    pass
-
-
-@export
-class LibGHDLException(GHDLBaseException):
+class DOMException(GHDLBaseException):
     pass
 
 
@@ -62,23 +55,11 @@ class GHDLException(GHDLBaseException):
 
 @export
 class GHDLMixin:
-    _MODE_TRANSLATION = {
-        nodes.Iir_Mode.In_Mode: Mode.In,
-        nodes.Iir_Mode.Out_Mode: Mode.Out,
-        nodes.Iir_Mode.Inout_Mode: Mode.InOut,
-        nodes.Iir_Mode.Buffer_Mode: Mode.Buffer,
-        nodes.Iir_Mode.Linkage_Mode: Mode.Linkage,
-    }
-
-    @classmethod
-    def _ghdlNodeToName(cls, node) -> str:
-        """Return the python string from node :obj:`node` identifier"""
-        return name_table.Get_Name_Ptr(nodes.Get_Identifier(node))
+    def CheckForErrors(self) -> None:
+        errorCount = errorout_memory.Get_Nbr_Messages()
+        if errorCount != 0:
+            for i in range(errorCount):
+                print(errorout_memory.Get_Error_Message(i + 1))
 
-    @classmethod
-    def _ghdlPortToMode(cls, port):
-        """Return the mode of a :obj:`port`."""
-        try:
-            return cls._MODE_TRANSLATION[nodes.Get_Mode(port)]
-        except KeyError:
-            raise LibGHDLException("Unknown mode.")
+            raise DOMException("Error in libghdl.") \
+                from LibGHDLException("libghdl: Internal error 2.")
diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py
index 4cf1ac2ad..9827cec24 100644
--- a/pyGHDL/dom/DesignUnit.py
+++ b/pyGHDL/dom/DesignUnit.py
@@ -1,19 +1,19 @@
 # =============================================================================
-#                ____ _   _ ____  _          _
-#   _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
-#  | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
-#  | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
-#  | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
-#  |_|    |___/
+#               ____ _   _ ____  _          _
+#  _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
+# | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_|    |___/
 # =============================================================================
-#  Authors:
-#    Patrick Lehmann
+# Authors:
+#   Patrick Lehmann
 #
-# Package module:   DOM: VHDL design units (e.g. entity or package).
+# Package module:   DOM: VHDL design units (e.g. context or package).
 #
 # License:
 # ============================================================================
-#  Copyright (C) 2019-2020 Tristan Gingold
+#  Copyright (C) 2019-2021 Tristan Gingold
 #
 #  This program is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@
 # ============================================================================
 
 """
-This module contains all DOM classes for VHDL's design units (:class:`entity <Entity>`,
+This module contains all DOM classes for VHDL's design units (:class:`context <Entity>`,
 :class:`architecture <Architecture>`, :class:`package <Package>`,
 :class:`package body <PackageBody>`, :class:`context <Context>` and
 :class:`configuration <Configuration>`.
@@ -41,56 +41,43 @@ This module contains all DOM classes for VHDL's design units (:class:`entity <En
 """
 from pydecor import export
 
-from pyVHDLModel.VHDLModel import Entity as VHDLModel_Entity
-from pyVHDLModel.VHDLModel import Architecture as VHDLModel_Architecture
-from pyVHDLModel.VHDLModel import Package as VHDLModel_Package
-from pyVHDLModel.VHDLModel import PackageBody as VHDLModel_PackageBody
-from pyVHDLModel.VHDLModel import Context as VHDLModel_Context
+from pyVHDLModel.VHDLModel import Entity        as VHDLModel_Entity
+from pyVHDLModel.VHDLModel import Architecture  as VHDLModel_Architecture
+from pyVHDLModel.VHDLModel import Package       as VHDLModel_Package
+from pyVHDLModel.VHDLModel import PackageBody   as VHDLModel_PackageBody
+from pyVHDLModel.VHDLModel import Context       as VHDLModel_Context
 from pyVHDLModel.VHDLModel import Configuration as VHDLModel_Configuration
 
+from pyGHDL.libghdl import utils
 from pyGHDL.libghdl.vhdl import nodes
-import pyGHDL.libghdl.utils as pyutils
 
-from pyGHDL.dom.Common import GHDLMixin
-from pyGHDL.dom.InterfaceItem import (
-    GenericConstantInterfaceItem,
-    PortSignalInterfaceItem,
-)
+from pyGHDL.dom._Utils import NodeToName, GetIirKindOfNode
+from pyGHDL.dom._Translate import GetExpressionFromNode, GetSubtypeIndicationFromNode, GetGenericsFromChainedNodes, GetPortsFromChainedNodes, \
+    GetDeclaredItemsFromChainedNodes
+from pyGHDL.dom.Common import GHDLMixin, DOMException
+from pyGHDL.dom.Object import Constant, Signal
 
 __all__ = []
 
 
 @export
 class Entity(VHDLModel_Entity, GHDLMixin):
+
     @classmethod
     def parse(cls, libraryUnit):
-        name = cls._ghdlNodeToName(libraryUnit)
+        name = NodeToName(libraryUnit)
         entity = cls(name)
 
-        cls.__parseGenerics(libraryUnit, entity)
-        cls.__parsePorts(libraryUnit, entity)
-
-        return entity
-
-    @classmethod
-    def __ghdlGetGenerics(cls, entity):
-        return pyutils.chain_iter(nodes.Get_Generic_Chain(entity))
+        for generic in GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(libraryUnit)):
+            entity.GenericItems.append(generic)
 
-    @classmethod
-    def __ghdlGetPorts(cls, entity):
-        return pyutils.chain_iter(nodes.Get_Port_Chain(entity))
+        for port in GetPortsFromChainedNodes(nodes.Get_Port_Chain(libraryUnit)):
+            entity.PortItems.append(port)
 
-    @classmethod
-    def __parseGenerics(cls, libraryUnit, entity):
-        for generic in cls.__ghdlGetGenerics(libraryUnit):
-            genericConstant = GenericConstantInterfaceItem.parse(generic)
-            entity.GenericItems.append(genericConstant)
+        for item in GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(libraryUnit), "entity", name):
+            entity.DeclaredItems.append(item)
 
-    @classmethod
-    def __parsePorts(cls, libraryUnit, entity):
-        for port in cls.__ghdlGetPorts(libraryUnit):
-            signalPort = PortSignalInterfaceItem.parse(port)
-            entity.PortItems.append(signalPort)
+        return entity
 
 
 @export
@@ -102,10 +89,15 @@ class Architecture(VHDLModel_Architecture, GHDLMixin):
 
     @classmethod
     def parse(cls, libraryUnit):
-        name = cls._ghdlNodeToName(libraryUnit)
-        entityName = cls._ghdlNodeToName(nodes.Get_Entity_Name(libraryUnit))
+        name = NodeToName(libraryUnit)
+        entityName = NodeToName(nodes.Get_Entity_Name(libraryUnit))
 
-        return cls(name, entityName)
+        architecture = cls(name, entityName)
+
+        for item in GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(libraryUnit), "architecture", name):
+            architecture.DeclaredItems.append(item)
+
+        return architecture
 
     def resolve(self):
         pass
@@ -113,31 +105,47 @@ class Architecture(VHDLModel_Architecture, GHDLMixin):
 
 @export
 class Package(VHDLModel_Package, GHDLMixin):
+
     @classmethod
     def parse(cls, libraryUnit):
-        name = cls._ghdlNodeToName(libraryUnit)
-        return cls(name)
+        name = NodeToName(libraryUnit)
+
+        package = cls(name)
+
+        for item in GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(libraryUnit), "package", name):
+            package.DeclaredItems.append(item)
+
+        return package
 
 
 @export
 class PackageBody(VHDLModel_PackageBody, GHDLMixin):
+
     @classmethod
     def parse(cls, libraryUnit):
-        name = cls._ghdlNodeToName(libraryUnit)
-        return cls(name)
+        name = NodeToName(libraryUnit)
+
+        packageBody = cls(name)
+
+        for item in GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(libraryUnit), "package body", name):
+            packageBody.DeclaredItems.append(item)
+
+        return packageBody
 
 
 @export
 class Context(VHDLModel_Context, GHDLMixin):
+
     @classmethod
     def parse(cls, libraryUnit):
-        name = cls._ghdlNodeToName(libraryUnit)
+        name = NodeToName(libraryUnit)
         return cls(name)
 
 
 @export
 class Configuration(VHDLModel_Configuration, GHDLMixin):
+
     @classmethod
     def parse(cls, libraryUnit):
-        name = cls._ghdlNodeToName(libraryUnit)
+        name = NodeToName(libraryUnit)
         return cls(name)
diff --git a/pyGHDL/dom/Expression.py b/pyGHDL/dom/Expression.py
new file mode 100644
index 000000000..7f32e7d54
--- /dev/null
+++ b/pyGHDL/dom/Expression.py
@@ -0,0 +1,287 @@
+# =============================================================================
+#               ____ _   _ ____  _          _
+#  _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
+# | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_|    |___/
+# =============================================================================
+# Authors:
+#   Patrick Lehmann
+#
+# Package module:   DOM: Interface items (e.g. generic or port)
+#
+# License:
+# ============================================================================
+#  Copyright (C) 2019-2021 Tristan Gingold
+#
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program.  If not, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from pydecor import export
+
+from pyVHDLModel.VHDLModel import \
+    InverseExpression as VHDLModel_InverseExpression, \
+    IdentityExpression as VHDLModel_IdentityExpression, \
+    NegationExpression as VHDLModel_NegationExpression, \
+    AbsoluteExpression as VHDLModel_AbsoluteExpression, \
+    TypeConversion as VHDLModel_TypeConversion, \
+    FunctionCall as VHDLModel_FunctionCall, \
+    QualifiedExpression as VHDLModel_QualifiedExpression, \
+    AdditionExpression as VHDLModel_AdditionExpression, \
+    SubtractionExpression as VHDLModel_SubtractionExpression, \
+    ConcatenationExpression as VHDLModel_ConcatenationExpression, \
+    MultiplyExpression as VHDLModel_MultiplyExpression, \
+    DivisionExpression as VHDLModel_DivisionExpression, \
+    RemainderExpression as VHDLModel_RemainderExpression, \
+    ModuloExpression as VHDLModel_ModuloExpression, \
+    ExponentiationExpression as VHDLModel_ExponentiationExpression, \
+    AndExpression as VHDLModel_AndExpression, \
+    NandExpression as VHDLModel_NandExpression, \
+    OrExpression as VHDLModel_OrExpression, \
+    NorExpression as VHDLModel_NorExpression, \
+    XorExpression as VHDLModel_XorExpression, \
+    XnorExpression as VHDLModel_XnorExpression, \
+    EqualExpression as VHDLModel_EqualExpression, \
+    UnequalExpression as VHDLModel_UnequalExpression, \
+    GreaterThanExpression as VHDLModel_GreaterThanExpression, \
+    GreaterEqualExpression as VHDLModel_GreaterEqualExpression, \
+    LessThanExpression as VHDLModel_LessThanExpression, \
+    ShiftRightLogicExpression as VHDLModel_ShiftRightLogicExpression, \
+    ShiftLeftLogicExpression as VHDLModel_ShiftLeftLogicExpression, \
+    ShiftRightArithmeticExpression as VHDLModel_ShiftRightArithmeticExpression, \
+    ShiftLeftArithmeticExpression as VHDLModel_ShiftLeftArithmeticExpression, \
+    RotateRightExpression as VHDLModel_RotateRightExpression, \
+    RotateLeftExpression as VHDLModel_RotateLeftExpression, \
+    Expression
+
+__all__ = []
+
+@export
+class InverseExpression(VHDLModel_InverseExpression):
+    def __init__(self, operand: Expression):
+        super().__init__()
+        self._operand = operand
+
+@export
+class IdentityExpression(VHDLModel_IdentityExpression):
+    def __init__(self, operand: Expression):
+        super().__init__()
+        self._operand = operand
+
+@export
+class NegationExpression(VHDLModel_NegationExpression):
+    def __init__(self, operand: Expression):
+        super().__init__()
+        self._operand = operand
+
+@export
+class AbsoluteExpression(VHDLModel_AbsoluteExpression):
+    def __init__(self, operand: Expression):
+        super().__init__()
+        self._operand = operand
+
+@export
+class TypeConversion(VHDLModel_TypeConversion):
+    def __init__(self, operand: Expression):
+        super().__init__()
+        self._operand = operand
+
+@export
+class FunctionCall(VHDLModel_FunctionCall):
+    def __init__(self, operand: Expression):
+        super().__init__()
+        self._operand = operand
+
+@export
+class QualifiedExpression(VHDLModel_QualifiedExpression):
+    def __init__(self, operand: Expression):
+        super().__init__()
+        self._operand = operand
+
+@export
+class AdditionExpression(VHDLModel_AdditionExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class SubtractionExpression(VHDLModel_SubtractionExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class ConcatenationExpression(VHDLModel_ConcatenationExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class MultiplyExpression(VHDLModel_MultiplyExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class DivisionExpression(VHDLModel_DivisionExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class RemainderExpression(VHDLModel_RemainderExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class ModuloExpression(VHDLModel_ModuloExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class ExponentiationExpression(VHDLModel_ExponentiationExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class AndExpression(VHDLModel_AndExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class NandExpression(VHDLModel_NandExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class OrExpression(VHDLModel_OrExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class NorExpression(VHDLModel_NorExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class XorExpression(VHDLModel_XorExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class XnorExpression(VHDLModel_XnorExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class EqualExpression(VHDLModel_EqualExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class UnequalExpression(VHDLModel_UnequalExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class GreaterThanExpression(VHDLModel_GreaterThanExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class GreaterEqualExpression(VHDLModel_GreaterEqualExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class LessThanExpression(VHDLModel_LessThanExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class ShiftRightLogicExpression(VHDLModel_ShiftRightLogicExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class ShiftLeftLogicExpression(VHDLModel_ShiftLeftLogicExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class ShiftRightArithmeticExpression(VHDLModel_ShiftRightArithmeticExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class ShiftLeftArithmeticExpression(VHDLModel_ShiftLeftArithmeticExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class RotateRightExpression(VHDLModel_RotateRightExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
+
+@export
+class RotateLeftExpression(VHDLModel_RotateLeftExpression):
+    def __init__(self, left: Expression, right: Expression):
+        super().__init__()
+        self._leftOperand = left
+        self._rightOperand = right
diff --git a/pyGHDL/dom/InterfaceItem.py b/pyGHDL/dom/InterfaceItem.py
index 0134655d5..89427e3b4 100644
--- a/pyGHDL/dom/InterfaceItem.py
+++ b/pyGHDL/dom/InterfaceItem.py
@@ -1,19 +1,19 @@
 # =============================================================================
-#                ____ _   _ ____  _          _
-#   _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
-#  | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
-#  | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
-#  | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
-#  |_|    |___/
+#               ____ _   _ ____  _          _
+#  _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
+# | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_|    |___/
 # =============================================================================
-#  Authors:
-#    Patrick Lehmann
+# Authors:
+#   Patrick Lehmann
 #
 # Package module:   DOM: Interface items (e.g. generic or port)
 #
 # License:
 # ============================================================================
-#  Copyright (C) 2019-2020 Tristan Gingold
+#  Copyright (C) 2019-2021 Tristan Gingold
 #
 #  This program is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
@@ -30,17 +30,16 @@
 #
 # SPDX-License-Identifier: GPL-2.0-or-later
 # ============================================================================
-
 from pydecor import export
 
-from pyVHDLModel.VHDLModel import (
-    PortSignalInterfaceItem as VHDLModel_PortSignalInterfaceItem,
-)
-from pyVHDLModel.VHDLModel import (
-    GenericConstantInterfaceItem as VHDLModel_GenericConstantInterfaceItem,
-)
+from pyVHDLModel.VHDLModel import \
+    GenericConstantInterfaceItem as VHDLModel_GenericConstantInterfaceItem, \
+    PortSignalInterfaceItem as VHDLModel_PortSignalInterfaceItem, \
+    Mode, SubTypeOrSymbol, Expression
 
-from pyGHDL.dom.Common import GHDLMixin
+from pyGHDL.dom._Utils     import NodeToName, GetModeOfNode
+from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode
+from pyGHDL.dom.Common     import GHDLMixin
 
 __all__ = []
 
@@ -49,21 +48,32 @@ __all__ = []
 class GenericConstantInterfaceItem(VHDLModel_GenericConstantInterfaceItem, GHDLMixin):
     @classmethod
     def parse(cls, generic):
-        name = cls._ghdlNodeToName(generic)
-        mode = cls._ghdlPortToMode(generic)
+        name = NodeToName(generic)
+        mode = GetModeOfNode(generic)
+        subTypeIndication = GetSubtypeIndicationFromNode(generic, "generic", name)
 
-        generic = cls(name, mode)
+        generic = cls(name, mode, subTypeIndication)
 
         return generic
 
+    def __init__(self, name:str, mode: Mode, subType: SubTypeOrSymbol):
+        super().__init__(name=name, mode=mode)
+        self._subType = subType
 
 @export
 class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem, GHDLMixin):
     @classmethod
     def parse(cls, port):
-        name = cls._ghdlNodeToName(port)
-        mode = cls._ghdlPortToMode(port)
+        name = NodeToName(port)
+        mode = GetModeOfNode(port)
+        subTypeIndication = GetSubtypeIndicationFromNode(port, "port", name)
 
-        port = cls(name, mode)
+        port = cls(name, mode, subTypeIndication)
 
         return port
+
+    def __init__(self, name:str, mode: Mode, subType: SubTypeOrSymbol, defaultExpression: Expression = None):
+        super().__init__(name=name, mode=mode)
+        self._subType = subType
+        self._defaultExpression = defaultExpression
+
diff --git a/pyGHDL/dom/Literal.py b/pyGHDL/dom/Literal.py
new file mode 100644
index 000000000..2ed1b5f65
--- /dev/null
+++ b/pyGHDL/dom/Literal.py
@@ -0,0 +1,55 @@
+# =============================================================================
+#               ____ _   _ ____  _          _
+#  _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
+# | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_|    |___/
+# =============================================================================
+# Authors:
+#   Patrick Lehmann
+#
+# Package module:   DOM: Interface items (e.g. generic or port)
+#
+# License:
+# ============================================================================
+#  Copyright (C) 2019-2021 Tristan Gingold
+#
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program.  If not, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from pydecor import export
+
+from pyVHDLModel.VHDLModel import \
+    IntegerLiteral as VHDLModel_IntegerLiteral, \
+    FloatingPointLiteral as VHDLModel_FloatingPointLiteral, \
+    CharacterLiteral as VHDLModel_CharacterLiteral
+
+__all__ = []
+
+
+@export
+class IntegerLiteral(VHDLModel_IntegerLiteral):
+    pass
+
+
+@export
+class FloatingPointLiteral(VHDLModel_FloatingPointLiteral):
+    pass
+
+
+@export
+class CharacterLiteral(VHDLModel_CharacterLiteral):
+    pass
diff --git a/pyGHDL/dom/Misc.py b/pyGHDL/dom/Misc.py
index 43c201c46..0f26119a2 100644
--- a/pyGHDL/dom/Misc.py
+++ b/pyGHDL/dom/Misc.py
@@ -1,19 +1,19 @@
 # =============================================================================
-#                ____ _   _ ____  _          _
-#   _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
-#  | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
-#  | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
-#  | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
-#  |_|    |___/
+#               ____ _   _ ____  _          _
+#  _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
+# | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_|    |___/
 # =============================================================================
-#  Authors:
-#    Patrick Lehmann
+# Authors:
+#   Patrick Lehmann
 #
 # Package module:   DOM: Elements not covered by the VHDL standard.
 #
 # License:
 # ============================================================================
-#  Copyright (C) 2019-2020 Tristan Gingold
+#  Copyright (C) 2019-2021 Tristan Gingold
 #
 #  This program is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
@@ -36,27 +36,22 @@
    Add a module documentation.
 """
 from pathlib import Path
-from typing import Any
+from typing  import Any
 
+import pyGHDL.libghdl.utils
 from pydecor import export
 
-from pyVHDLModel.VHDLModel import Design as VHDLModel_Design
-from pyVHDLModel.VHDLModel import Library as VHDLModel_Library
-from pyVHDLModel.VHDLModel import Document as VHDLModel_Document
+from pyGHDL.dom._Utils import GetIirKindOfNode
+from pyVHDLModel.VHDLModel import Design        as VHDLModel_Design
+from pyVHDLModel.VHDLModel import Library       as VHDLModel_Library
+from pyVHDLModel.VHDLModel import Document      as VHDLModel_Document
 
-import pyGHDL.libghdl as libghdl
-from pyGHDL.libghdl import name_table, files_map, errorout_memory
-from pyGHDL.libghdl.vhdl import nodes, sem_lib
+import pyGHDL.libghdl       as libghdl
+from pyGHDL.libghdl import name_table, files_map, errorout_memory, LibGHDLException, utils
+from pyGHDL.libghdl.vhdl    import nodes, sem_lib
 
-from pyGHDL.dom.Common import LibGHDLException, GHDLException
-from pyGHDL.dom.DesignUnit import (
-    Entity,
-    Architecture,
-    Package,
-    PackageBody,
-    Context,
-    Configuration,
-)
+from pyGHDL.dom.Common      import DOMException, GHDLMixin
+from pyGHDL.dom.DesignUnit  import Entity, Architecture, Package, PackageBody, Context, Configuration
 
 __all__ = []
 
@@ -90,61 +85,66 @@ class Library(VHDLModel_Library):
 
 
 @export
-class Document(VHDLModel_Document):
+class Document(VHDLModel_Document, GHDLMixin):
     __ghdlFileID: Any
     __ghdlSourceFileEntry: Any
     __ghdlFile: Any
 
     def __init__(self, path: Path = None, dontParse: bool = False):
         super().__init__(path)
+        GHDLMixin.__init__(self)
 
         self.__ghdl_init()
-        if dontParse == False:
+        if (dontParse == False):
             self.parse()
 
     def __ghdl_init(self):
         # Read input file
         self.__ghdlFileID = name_table.Get_Identifier(str(self.Path))
-        self.__ghdlSourceFileEntry = files_map.Read_Source_File(
-            name_table.Null_Identifier, self.__ghdlFileID
-        )
+        self.__ghdlSourceFileEntry = files_map.Read_Source_File(name_table.Null_Identifier, self.__ghdlFileID)
         if self.__ghdlSourceFileEntry == files_map.No_Source_File_Entry:
             raise LibGHDLException("Cannot load file '{!s}'".format(self.Path))
 
-        # parse
+        self.CheckForErrors()
+
+        # Parse input file
         self.__ghdlFile = sem_lib.Load_File(self.__ghdlSourceFileEntry)
 
+        self.CheckForErrors()
+
     def parse(self):
-        unit = nodes.Get_First_Design_Unit(self.__ghdlFile)
-        while unit != nodes.Null_Iir:
+        firstUnit = nodes.Get_First_Design_Unit(self.__ghdlFile)
+
+        for unit in utils.chain_iter(firstUnit):
             libraryUnit = nodes.Get_Library_Unit(unit)
-            nodeKind = nodes.Get_Kind(libraryUnit)
+            nodeKind = GetIirKindOfNode(libraryUnit)
 
-            if nodeKind == nodes.Iir_Kind.Entity_Declaration:
+            if (nodeKind == nodes.Iir_Kind.Entity_Declaration):
                 entity = Entity.parse(libraryUnit)
                 self.Entities.append(entity)
 
-            elif nodeKind == nodes.Iir_Kind.Architecture_Body:
+            elif (nodeKind == nodes.Iir_Kind.Architecture_Body):
                 architecture = Architecture.parse(libraryUnit)
                 self.Architectures.append(architecture)
 
-            elif nodeKind == nodes.Iir_Kind.Package_Declaration:
+            elif (nodeKind == nodes.Iir_Kind.Package_Declaration):
                 package = Package.parse(libraryUnit)
                 self.Packages.append(package)
 
-            elif nodeKind == nodes.Iir_Kind.Package_Body:
+            elif (nodeKind == nodes.Iir_Kind.Package_Body):
                 packageBody = PackageBody.parse(libraryUnit)
                 self.PackageBodies.append(packageBody)
 
-            elif nodeKind == nodes.Iir_Kind.Context_Declaration:
+            elif (nodeKind == nodes.Iir_Kind.Context_Declaration):
                 context = Context.parse(libraryUnit)
                 self.Contexts.append(context)
 
-            elif nodeKind == nodes.Iir_Kind.Configuration_Declaration:
+            elif (nodeKind == nodes.Iir_Kind.Configuration_Declaration):
                 configuration = Configuration.parse(libraryUnit)
                 self.Configurations.append(configuration)
 
             else:
-                raise GHDLException("Unknown design unit kind.")
-
-            unit = nodes.Get_Chain(unit)
+                raise DOMException(
+                    "Unknown design unit kind '{kindName}'({kind}).".format(
+                        kindName=nodeKind.name, kind=nodeKind)
+                )
diff --git a/pyGHDL/dom/Object.py b/pyGHDL/dom/Object.py
new file mode 100644
index 000000000..924c28662
--- /dev/null
+++ b/pyGHDL/dom/Object.py
@@ -0,0 +1,72 @@
+# =============================================================================
+#               ____ _   _ ____  _          _
+#  _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
+# | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_|    |___/
+# =============================================================================
+# Authors:
+#   Patrick Lehmann
+#
+# Package module:   DOM: Interface items (e.g. generic or port)
+#
+# License:
+# ============================================================================
+#  Copyright (C) 2019-2021 Tristan Gingold
+#
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program.  If not, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from pydecor import export
+
+from pyVHDLModel.VHDLModel import \
+    Constant as VHDLModel_Constant, \
+    Variable as VHDLModel_Variable, \
+    Signal as VHDLModel_Signal, \
+    Expression, SubTypeOrSymbol
+
+__all__ = []
+
+
+@export
+class Constant(VHDLModel_Constant):
+    def __init__(self, name: str, subType: SubTypeOrSymbol, defaultExpression: Expression):
+        super().__init__(name)
+
+        self._name = name
+        self._subType = subType
+        self._defaultExpression = defaultExpression
+
+
+@export
+class Variable(VHDLModel_Variable):
+    def __init__(self, name: str, subType: SubTypeOrSymbol, defaultExpression: Expression):
+        super().__init__(name)
+
+        self._name = name
+        self._subType = subType
+        self._defaultExpression = defaultExpression
+
+
+@export
+class Signal(VHDLModel_Signal):
+    def __init__(self, name: str, subType: SubTypeOrSymbol, defaultExpression: Expression):
+        super().__init__(name)
+
+        self._name = name
+        self._subType = subType
+        self._defaultExpression = defaultExpression
+
diff --git a/pyGHDL/dom/Range.py b/pyGHDL/dom/Range.py
new file mode 100644
index 000000000..45675cd19
--- /dev/null
+++ b/pyGHDL/dom/Range.py
@@ -0,0 +1,58 @@
+# =============================================================================
+#               ____ _   _ ____  _          _
+#  _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
+# | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_|    |___/
+# =============================================================================
+# Authors:
+#   Patrick Lehmann
+#
+# Package module:   DOM: Interface items (e.g. generic or port)
+#
+# License:
+# ============================================================================
+#  Copyright (C) 2019-2021 Tristan Gingold
+#
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program.  If not, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from pydecor import export
+
+from pyVHDLModel.VHDLModel import \
+    Range as VHDLModel_Range, \
+    RangeExpression as VHDLModel_RangeExpression, \
+    Direction, Expression
+
+__all__ = []
+
+
+@export
+class Range(VHDLModel_Range):
+    def __init__(self, left: Expression, right: Expression, direction: Direction):
+        super().__init__()
+
+        self._leftBound = left
+        self._rightBound = right
+        self._direction = direction
+
+
+@export
+class RangeExpression(VHDLModel_RangeExpression):
+    def __init__(self, range: Range):
+        super().__init__()
+
+        self._range = range
diff --git a/pyGHDL/dom/Symbol.py b/pyGHDL/dom/Symbol.py
new file mode 100644
index 000000000..9b765872d
--- /dev/null
+++ b/pyGHDL/dom/Symbol.py
@@ -0,0 +1,60 @@
+# =============================================================================
+#               ____ _   _ ____  _          _
+#  _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
+# | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_|    |___/
+# =============================================================================
+# Authors:
+#   Patrick Lehmann
+#
+# Package module:   DOM: Interface items (e.g. generic or port)
+#
+# License:
+# ============================================================================
+#  Copyright (C) 2019-2021 Tristan Gingold
+#
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program.  If not, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from pydecor import export
+
+from typing import List
+
+from pyVHDLModel.VHDLModel import \
+    SimpleSubTypeSymbol as VHDLModel_SimpleSubTypeSymbol, \
+    ConstrainedSubTypeSymbol as VHDLModel_ConstrainedSubTypeSymbol, \
+    SimpleObjectSymbol as VHDLModel_SimpleObjectSymbol, \
+    Constraint
+
+__all__ = []
+
+
+@export
+class SimpleSubTypeSymbol(VHDLModel_SimpleSubTypeSymbol):
+    def __init__(self, subTypeName: str):
+        super().__init__(subTypeName=subTypeName)
+
+
+@export
+class ConstrainedSubTypeSymbol(VHDLModel_ConstrainedSubTypeSymbol):
+    def __init__(self, subTypeName: str, constraints: List[Constraint] = None):
+        super().__init__(subTypeName=subTypeName, constraints=constraints)
+
+@export
+class SimpleObjectSymbol(VHDLModel_SimpleObjectSymbol):
+    def __init__(self, symbolName: str):
+        super().__init__(symbolName)
diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py
new file mode 100644
index 000000000..e93b20b07
--- /dev/null
+++ b/pyGHDL/dom/_Translate.py
@@ -0,0 +1,208 @@
+from typing import List
+
+
+from pydecor import export
+from pyVHDLModel.VHDLModel import Constraint, Direction, Expression, SubTypeOrSymbol
+
+from pyGHDL.libghdl import utils, name_table
+from pyGHDL.libghdl.utils  import flist_iter
+from pyGHDL.libghdl.vhdl   import nodes
+from pyGHDL.dom._Utils     import NodeToName, GetIirKindOfNode
+from pyGHDL.dom.Common     import DOMException
+from pyGHDL.dom.Range      import Range, RangeExpression
+from pyGHDL.dom.Symbol     import SimpleObjectSymbol, SimpleSubTypeSymbol, ConstrainedSubTypeSymbol
+from pyGHDL.dom.Literal import IntegerLiteral, CharacterLiteral, FloatingPointLiteral
+from pyGHDL.dom.Expression import SubtractionExpression, AdditionExpression, MultiplyExpression, DivisionExpression, InverseExpression, ExponentiationExpression
+
+__all__ = []
+
+
+@export
+def GetSubtypeIndicationFromNode(node, entity: str, name: str) -> SubTypeOrSymbol:
+    subTypeIndication = nodes.Get_Subtype_Indication(node)
+    subTypeKind = GetIirKindOfNode(subTypeIndication)
+
+    if (subTypeKind == nodes.Iir_Kind.Simple_Name):
+        subTypeName = NodeToName(subTypeIndication)
+
+        subType = SimpleSubTypeSymbol(subTypeName)
+    elif (subTypeKind == nodes.Iir_Kind.Array_Subtype_Definition):
+        typeMark = nodes.Get_Subtype_Type_Mark(subTypeIndication)
+        typeMarkName = NodeToName(typeMark)
+
+        constraints = GetArrayConstraintsFromSubtypeIndication(subTypeIndication)
+        subType = ConstrainedSubTypeSymbol(typeMarkName, constraints)
+    elif (subTypeKind == nodes.Iir_Kind.Subtype_Definition):
+        raise DOMException(
+            "Unknown handling of subtype kind '{kind}' of subtype indication '{indication}' while parsing {entity} '{name}'.".format(
+                kind=subTypeKind, indication=subTypeIndication, entity=entity, name=name)
+        )
+    else:
+        raise DOMException(
+            "Unknown subtype kind '{kind}' of subtype indication '{indication}' while parsing {entity} '{name}'.".format(
+                kind=subTypeKind, indication=subTypeIndication, entity=entity, name=name)
+        )
+
+    return subType
+
+@export
+def GetArrayConstraintsFromSubtypeIndication(subTypeIndication) -> List[Constraint]:
+    constraints = []
+    for constraint in flist_iter(nodes.Get_Index_Constraint_List(subTypeIndication)):
+        constraintKind = GetIirKindOfNode(constraint)
+        if constraintKind == nodes.Iir_Kind.Range_Expression:
+            direction = nodes.Get_Direction(constraint)
+            leftBound = nodes.Get_Left_Limit_Expr(constraint)
+            rightBound = nodes.Get_Right_Limit_Expr(constraint)
+
+            r = Range(
+                GetExpressionFromNode(leftBound),
+                GetExpressionFromNode(rightBound),
+                Direction.DownTo if direction else Direction.To
+            )
+            constraints.append(RangeExpression(r))
+        elif constraintKind == nodes.Iir_Kind.Attribute_Name:
+            raise DOMException("[NOT IMPLEMENTED] Attribute name as range.")
+        elif constraintKind == nodes.Iir_Kind.Simple_Name:
+            raise DOMException("[NOT IMPLEMENTED] Subtype as range.")
+        else:
+            raise DOMException(
+                "Unknown constraint kind '{kind}' for constraint '{constraint}' in subtype indication '{indication}'.".format(
+                    kind=constraintKind, constraint=constraint, indication=subTypeIndication)
+            )
+
+    return constraints
+
+
+@export
+def GetExpressionFromNode(node) -> Expression:
+    kind = GetIirKindOfNode(node)
+
+    if kind == nodes.Iir_Kind.Simple_Name:
+        name = NodeToName(node)
+        return SimpleObjectSymbol(name)
+    elif kind == nodes.Iir_Kind.Integer_Literal:
+        integerLiteralValue = nodes.Get_Value(node)
+        return IntegerLiteral(integerLiteralValue)
+    elif kind == nodes.Iir_Kind.Floating_Point_Literal:
+        fpLiteralValue = nodes.Get_Fp_Value(node)
+        return FloatingPointLiteral(fpLiteralValue)
+    elif kind == nodes.Iir_Kind.Character_Literal:
+        identifier = nodes.Get_Identifier(node)
+        characterLiteralValue = name_table.Get_Character(identifier)
+        return CharacterLiteral(characterLiteralValue)
+    elif kind == nodes.Iir_Kind.Negation_Operator:
+        operand = GetExpressionFromNode(nodes.Get_Operand(node))
+        return InverseExpression(operand)
+    elif kind == nodes.Iir_Kind.Addition_Operator:
+        left = GetExpressionFromNode(nodes.Get_Left(node))
+        right = GetExpressionFromNode(nodes.Get_Right(node))
+        return AdditionExpression(left, right)
+    elif kind == nodes.Iir_Kind.Substraction_Operator:
+        left = GetExpressionFromNode(nodes.Get_Left(node))
+        right = GetExpressionFromNode(nodes.Get_Right(node))
+        return SubtractionExpression(left, right)
+    elif kind == nodes.Iir_Kind.Multiplication_Operator:
+        left = GetExpressionFromNode(nodes.Get_Left(node))
+        right = GetExpressionFromNode(nodes.Get_Right(node))
+        return MultiplyExpression(left, right)
+    elif kind == nodes.Iir_Kind.Division_Operator:
+        left = GetExpressionFromNode(nodes.Get_Left(node))
+        right = GetExpressionFromNode(nodes.Get_Right(node))
+        return DivisionExpression(left, right)
+    elif kind == nodes.Iir_Kind.Exponentiation_Operator:
+        left = GetExpressionFromNode(nodes.Get_Left(node))
+        right = GetExpressionFromNode(nodes.Get_Right(node))
+        return ExponentiationExpression(left, right)
+    else:
+        raise DOMException(
+            "Unknown expression kind '{kindName}'({kind}) in expression '{expr}'.".format(
+                kind=kind, kindName=kind.name, expr=node)
+        )
+
+# FIXME: rewrite to generator
+@export
+def GetGenericsFromChainedNodes(nodeChain):
+    result = []
+    for generic in utils.chain_iter(nodeChain):
+        kind = GetIirKindOfNode(generic)
+        if kind == nodes.Iir_Kind.Interface_Constant_Declaration:
+            from pyGHDL.dom.InterfaceItem import GenericConstantInterfaceItem
+
+            genericConstant = GenericConstantInterfaceItem.parse(generic)
+
+            result.append(genericConstant)
+        else:
+            raise DOMException(
+                "Unknown generic kind '{kindName}'({kind}) in generic '{generic}'.".format(
+                    kind=kind, kindName=kind.name, generic=generic)
+            )
+
+    return result
+
+# FIXME: rewrite to generator
+@export
+def GetPortsFromChainedNodes(nodeChain):
+    result = []
+    for port in utils.chain_iter(nodeChain):
+        kind = GetIirKindOfNode(port)
+        if kind == nodes.Iir_Kind.Interface_Signal_Declaration:
+            from pyGHDL.dom.InterfaceItem import PortSignalInterfaceItem
+
+            portSignal = PortSignalInterfaceItem.parse(port)
+
+            result.append(portSignal)
+        else:
+            raise DOMException(
+                "Unknown port kind '{kindName}'({kind}) in port '{port}'.".format(
+                    kind=kind, kindName=kind.name, port=port)
+            )
+
+    return result
+
+def GetDeclaredItemsFromChainedNodes(nodeChain, entity: str, name: str):
+    result = []
+    for item in utils.chain_iter(nodeChain):
+        kind = GetIirKindOfNode(item)
+        if kind == nodes.Iir_Kind.Constant_Declaration:
+            from pyGHDL.dom.Object import Constant
+
+            constantName = NodeToName(item)
+            subTypeIndication = GetSubtypeIndicationFromNode(item, "constant", constantName)
+            defaultExpression = GetExpressionFromNode(nodes.Get_Default_Value(item))
+
+            constant = Constant(constantName, subTypeIndication, defaultExpression)
+
+            result.append(constant)
+        elif kind == nodes.Iir_Kind.Signal_Declaration:
+            from pyGHDL.dom.Object import Signal
+
+            signalName = NodeToName(item)
+            subTypeIndication = GetSubtypeIndicationFromNode(item, "signal", signalName)
+            defaultExpression = GetExpressionFromNode(nodes.Get_Default_Value(item))
+
+            constant = Signal(signalName, subTypeIndication, defaultExpression)
+
+            result.append(constant)
+        elif kind == nodes.Iir_Kind.Anonymous_Type_Declaration:
+            typeName = NodeToName(item)
+            print("found type '{name}'".format(name=typeName))
+        elif kind == nodes.Iir_Kind.Subtype_Declaration:
+            subTypeName = NodeToName(item)
+            print("found subtype '{name}'".format(name=subTypeName))
+        elif kind == nodes.Iir_Kind.Function_Declaration:
+            functionName = NodeToName(item)
+            print("found function '{name}'".format(name=functionName))
+        elif kind == nodes.Iir_Kind.Function_Body:
+            #                functionName = NodeToName(item)
+            print("found function body '{name}'".format(name="????"))
+        elif kind == nodes.Iir_Kind.Object_Alias_Declaration:
+            aliasName = NodeToName(item)
+            print("found alias '{name}'".format(name=aliasName))
+        else:
+            raise DOMException(
+                "Unknown declared item kind '{kindName}'({kind}) in {entity} '{name}'.".format(
+                    kind=kind, kindName=kind.name, entity=entity, name=name)
+            )
+
+    return result
diff --git a/pyGHDL/dom/_Utils.py b/pyGHDL/dom/_Utils.py
new file mode 100644
index 000000000..f0c838517
--- /dev/null
+++ b/pyGHDL/dom/_Utils.py
@@ -0,0 +1,38 @@
+from pydecor import export
+
+from pyVHDLModel.VHDLModel import  Mode
+
+from pyGHDL.libghdl      import LibGHDLException, name_table
+from pyGHDL.libghdl.vhdl import nodes
+
+
+__all__ = []
+
+__MODE_TRANSLATION = {
+    nodes.Iir_Mode.In_Mode:      Mode.In,
+    nodes.Iir_Mode.Out_Mode:     Mode.Out,
+    nodes.Iir_Mode.Inout_Mode:   Mode.InOut,
+    nodes.Iir_Mode.Buffer_Mode:  Mode.Buffer,
+    nodes.Iir_Mode.Linkage_Mode: Mode.Linkage
+}
+
+@export
+def GetIirKindOfNode(node) -> nodes.Iir_Kind:
+    kind: int = nodes.Get_Kind(node)
+    return nodes.Iir_Kind(kind)
+
+
+@export
+def NodeToName(node) -> str:
+    """Return the python string from node :obj:`node` identifier"""
+    identifier = nodes.Get_Identifier(node)
+    return name_table.Get_Name_Ptr(identifier)
+
+
+@export
+def GetModeOfNode(node) -> Mode:
+    """Return the mode of a :obj:`port`."""
+    try:
+        return __MODE_TRANSLATION[nodes.Get_Mode(node)]
+    except KeyError:
+        raise LibGHDLException("Unknown mode.")
diff --git a/pyGHDL/dom/__init__.py b/pyGHDL/dom/__init__.py
index b57c20c28..b4ffaf4c6 100644
--- a/pyGHDL/dom/__init__.py
+++ b/pyGHDL/dom/__init__.py
@@ -1,19 +1,19 @@
 # =============================================================================
-#                ____ _   _ ____  _          _
-#   _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
-#  | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
-#  | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
-#  | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
-#  |_|    |___/
+#               ____ _   _ ____  _          _
+#  _ __  _   _ / ___| | | |  _ \| |      __| | ___  _ __ ___
+# | '_ \| | | | |  _| |_| | | | | |     / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| |  _  | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_|    |___/
 # =============================================================================
-#  Authors:
-#    Patrick Lehmann
+# Authors:
+#   Patrick Lehmann
 #
 # Package package:  Document object model (DOM) for pyGHDL.libghdl.
 #
 # License:
 # ============================================================================
-#  Copyright (C) 2019-2020 Tristan Gingold
+#  Copyright (C) 2019-2021 Tristan Gingold
 #
 #  This program is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
@@ -31,6 +31,4 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 # ============================================================================
 
-from pydecor import export
-
 __all__ = []
diff --git a/pyGHDL/dom/formatting/__init__.py b/pyGHDL/dom/formatting/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py
new file mode 100644
index 000000000..a64f2a4f5
--- /dev/null
+++ b/pyGHDL/dom/formatting/prettyprint.py
@@ -0,0 +1,296 @@
+from typing import List, Union
+
+from pydecor import export
+
+from pyGHDL.dom.Object import Constant, Signal
+from pyVHDLModel.VHDLModel import GenericInterfaceItem, Expression, Direction, Mode, NamedEntity, PortInterfaceItem, BinaryExpression, IdentityExpression, \
+    UnaryExpression
+
+from pyGHDL import GHDLBaseException
+from pyGHDL.dom.Misc import Document
+from pyGHDL.dom.DesignUnit import Entity, Architecture, Package, PackageBody, Configuration, Context
+from pyGHDL.dom.InterfaceItem import GenericConstantInterfaceItem, PortSignalInterfaceItem
+from pyGHDL.dom.Symbol import SimpleSubTypeSymbol, ConstrainedSubTypeSymbol, SimpleObjectSymbol
+from pyGHDL.dom.Literal import IntegerLiteral, CharacterLiteral, FloatingPointLiteral
+
+from pyGHDL.dom.Expression import SubtractionExpression, AdditionExpression, MultiplyExpression, DivisionExpression, InverseExpression, AbsoluteExpression, \
+    NegationExpression, ExponentiationExpression
+
+StringBuffer = List[str]
+
+DirectionTranslation = {
+    Direction.To:     "to",
+    Direction.DownTo: "downto"
+}
+
+ModeTranslation = {
+    Mode.In:      "in",
+    Mode.Out:     "out",
+    Mode.InOut:   "inout",
+    Mode.Buffer:  "buffer",
+    Mode.Linkage: "linkage"
+}
+
+UnaryExpressionTranslation = {
+    IdentityExpression:    " +",
+    NegationExpression:    " -",
+    InverseExpression:     "not ",
+    AbsoluteExpression:    "abs ",
+}
+
+BinaryExpressionTranslation = {
+    AdditionExpression:       " + ",
+    SubtractionExpression:    " - ",
+    MultiplyExpression:       " * ",
+    DivisionExpression:       " / ",
+    ExponentiationExpression: "**"
+}
+
+@export
+class PrettyPrintException(GHDLBaseException):
+    pass
+
+@export
+class PrettyPrint:
+    # _buffer: StringBuffer
+    #
+    # def __init__(self):
+    #     self._buffer = []
+
+    def formatDocument(self, document: Document, level: int = 0) -> StringBuffer:
+        buffer = []
+        prefix = "  " * level
+        buffer.append("{prefix}Document '{doc!s}':".format(doc=document.Path, prefix=prefix))
+        buffer.append("{prefix}  Entities:".format(prefix=prefix))
+        for entity in document.Entities:
+            for line in self.formatEntity(entity, level+1):
+                buffer.append(line)
+        buffer.append("{prefix}  Architectures:".format(prefix=prefix))
+        for architecture in document.Architectures:
+            for line in self.formatArchitecture(architecture, level+1):
+                buffer.append(line)
+        buffer.append("{prefix}  Packages:".format(prefix=prefix))
+        for package in document.Packages:
+            for line in self.formatPackage(package, level+1):
+                buffer.append(line)
+        buffer.append("{prefix}  PackageBodies:".format(prefix=prefix))
+        for packageBodies in document.PackageBodies:
+            for line in self.formatPackageBody(packageBodies, level+1):
+                buffer.append(line)
+        buffer.append("{prefix}  Configurations:".format(prefix=prefix))
+        for configuration in document.Configurations:
+            for line in self.formatConfiguration(configuration, level+1):
+                buffer.append(line)
+        buffer.append("{prefix}  Contexts:".format(prefix=prefix))
+        for context in document.Contexts:
+            for line in self.formatContext(context, level+1):
+                buffer.append(line)
+
+        return buffer
+
+    def formatEntity(self, entity: Entity, level: int = 0) -> StringBuffer:
+        buffer = []
+        prefix = "  " * level
+        buffer.append("{prefix}- {name}".format(name=entity.Name, prefix=prefix))
+        buffer.append("{prefix}  Generics:".format(prefix=prefix))
+        for generic in entity.GenericItems:
+            for line in self.formatGeneric(generic, level + 1):
+                buffer.append(line)
+        buffer.append("{prefix}  Ports:".format(prefix=prefix))
+        for port in entity.PortItems:
+            for line in self.formatPort(port, level + 1):
+                buffer.append(line)
+        buffer.append("{prefix}  Declared:".format(prefix=prefix))
+        for item in entity.DeclaredItems:
+            for line in self.formatDeclaredItems(item, level + 1):
+                buffer.append(line)
+
+        return buffer
+
+    def formatArchitecture(self, architecture: Architecture, level: int = 0) -> StringBuffer:
+        buffer = []
+        prefix = "  " * level
+        buffer.append("{prefix}- {name}".format(name=architecture.Name, prefix=prefix))
+        buffer.append("{prefix}  Declared:".format(prefix=prefix))
+        for item in architecture.DeclaredItems:
+            for line in self.formatDeclaredItems(item, level + 2):
+                buffer.append(line)
+
+        return buffer
+
+    def formatPackage(self, package: Package, level: int = 0) -> StringBuffer:
+        buffer = []
+        prefix = "  " * level
+        buffer.append("{prefix}- {name}".format(name=package.Name, prefix=prefix))
+        buffer.append("{prefix}  Declared:".format(prefix=prefix))
+        for item in package.DeclaredItems:
+            for line in self.formatDeclaredItems(item, level + 1):
+                buffer.append(line)
+
+        return buffer
+
+    def formatPackageBody(self, packageBody: PackageBody, level: int = 0) -> StringBuffer:
+        buffer = []
+        prefix = "  " * level
+        buffer.append("{prefix}- {name}".format(name=packageBody.Name, prefix=prefix))
+        buffer.append("{prefix}  Declared:".format(prefix=prefix))
+        for item in packageBody.DeclaredItems:
+            for line in self.formatDeclaredItems(item, level + 1):
+                buffer.append(line)
+
+        return buffer
+
+    def formatConfiguration(self, configuration: Configuration, level: int = 0) -> StringBuffer:
+        buffer = []
+        prefix = "  " * level
+        buffer.append("{prefix}- {name}".format(name=configuration.Name, prefix=prefix))
+
+        return buffer
+
+    def formatContext(self, context: Context, level: int = 0) -> StringBuffer:
+        buffer = []
+        prefix = "  " * level
+        buffer.append("{prefix}- {name}".format(name=context.Name, prefix=prefix))
+
+        return buffer
+
+    def formatGeneric(self, generic: Union[NamedEntity, GenericInterfaceItem], level: int = 0) -> StringBuffer:
+        if isinstance(generic, GenericConstantInterfaceItem):
+            return self.formatGenericConstant(generic, level)
+        else:
+            raise PrettyPrintException("Unhandled generic kind for generic '{name}'.".format(name=generic.Name))
+
+    def formatPort(self, port: Union[NamedEntity, PortInterfaceItem], level: int = 0) -> StringBuffer:
+        if isinstance(port, PortSignalInterfaceItem):
+            return self.formatPortSignal(port, level)
+        else:
+            raise PrettyPrintException("Unhandled port kind for port '{name}'.".format(name=port.Name))
+
+    def formatGenericConstant(self, generic: GenericConstantInterfaceItem, level: int = 0) -> StringBuffer:
+        buffer = []
+        prefix = "  " * level
+        subType = generic.SubType
+        if isinstance(subType, SimpleSubTypeSymbol):
+            buffer.append(
+                "{prefix}  - {name} : {mode} {type}".format(
+                    prefix=prefix,
+                    name=generic.Name,
+                    mode=ModeTranslation[generic.Mode],
+                    type=subType.SymbolName
+                )
+            )
+        elif isinstance(subType, ConstrainedSubTypeSymbol):
+            buffer.append(
+                "{prefix}  - {name} : {mode} {type}({constraints})".format(
+                    prefix=prefix,
+                    name=generic.Name,
+                    mode=ModeTranslation[generic.Mode],
+                    type=subType.SymbolName,
+                    constraints=", ".join(
+                        ["{left} {dir} {right}".format(
+                            left=self.formatExpression(constraint.Range.LeftBound),
+                            right=self.formatExpression(constraint.Range.RightBound),
+                            dir=DirectionTranslation[constraint.Range.Direction])
+                                for constraint in subType.Constraints])
+                )
+            )
+        else:
+            raise PrettyPrintException("Unhandled constraint kind for generic '{name}'.".format(name=generic.Name))
+
+        return buffer
+
+    def formatPortSignal(self, port: PortSignalInterfaceItem, level: int = 0) -> StringBuffer:
+        buffer = []
+        prefix = "  " * level
+
+        buffer.append(
+            "{prefix}  - {name} : {mode} {subtypeindication}".format(
+                prefix=prefix,
+                name=port.Name,
+                mode=ModeTranslation[port.Mode],
+                subtypeindication=self.formatSubtypeIndication(port.SubType, "port", port.Name)
+            )
+        )
+
+        return buffer
+
+    def formatDeclaredItems(self, item, level: int = 0) -> StringBuffer:
+        buffer = []
+        prefix = "  " * level
+
+        if isinstance(item, Constant):
+            buffer.append(
+                "{prefix}- constant {name} : {subtype} := {expr}".format(
+                    prefix=prefix,
+                    name=item.Name,
+                    subtype=self.formatSubtypeIndication(item.SubType, "constant", item.Name),
+                    expr=self.formatExpression(item.DefaultExpression)
+                )
+            )
+        elif isinstance(item, Signal):
+            buffer.append(
+                "{prefix}- signal {name} : {subtype}{initValue}".format(
+                    prefix=prefix,
+                    name=item.Name,
+                    subtype=self.formatSubtypeIndication(item.SubType, "signal", item.Name),
+                    initValue=" := {expr}".format(
+                        expr=self.formatExpression(item.DefaultExpression)
+                    ) if item.DefaultExpression is not None else ""
+                )
+            )
+        else:
+            raise PrettyPrintException("Unhandled declared item kind.")
+
+        return buffer
+
+    def formatSubtypeIndication(self, subTypeIndication, entity: str, name: str) -> str:
+        if isinstance(subTypeIndication, SimpleSubTypeSymbol):
+            return "{type}".format(type=subTypeIndication.SymbolName)
+        elif isinstance(subTypeIndication, ConstrainedSubTypeSymbol):
+            constraints = ", ".join(
+                ["{left} {dir} {right}".format(
+                    left=self.formatExpression(constraint.Range.LeftBound),
+                    right=self.formatExpression(constraint.Range.RightBound),
+                    dir=DirectionTranslation[constraint.Range.Direction]
+                ) for constraint in subTypeIndication.Constraints]
+            )
+
+            return "{type}({constraints})".format(
+                type=subTypeIndication.SymbolName,
+                constraints=constraints
+            )
+        else:
+            raise PrettyPrintException("Unhandled constraint kind for {entity} '{name}'.".format(entity=entity, name=name))
+
+    def formatExpression(self, expression: Expression) -> str:
+        if isinstance(expression, SimpleObjectSymbol):
+            return "{name}".format(name=expression.SymbolName)
+        elif isinstance(expression, IntegerLiteral):
+            return "{value}".format(value=expression.Value)
+        elif isinstance(expression, FloatingPointLiteral):
+            return "{value}".format(value=expression.Value)
+        elif isinstance(expression, CharacterLiteral):
+            return "'{value}'".format(value=expression.Value)
+        elif isinstance(expression, UnaryExpression):
+            try:
+                operator = UnaryExpressionTranslation[type(expression)]
+            except KeyError:
+                raise PrettyPrintException("Unhandled operator for unary expression.")
+
+            return "{operator}{operand}".format(
+                operand=self.formatExpression(expression.Operand),
+                operator=operator
+            )
+        elif isinstance(expression, BinaryExpression):
+            try:
+                operator = BinaryExpressionTranslation[type(expression)]
+            except KeyError:
+                raise PrettyPrintException("Unhandled operator for binary expression.")
+
+            return "{left}{operator}{right}".format(
+                left=self.formatExpression(expression.LeftOperand),
+                right=self.formatExpression(expression.RightOperand),
+                operator=operator
+            )
+        else:
+            raise PrettyPrintException("Unhandled expression kind.")
diff --git a/pyGHDL/requirements.txt b/pyGHDL/requirements.txt
index d373926f3..97d65b84a 100644
--- a/pyGHDL/requirements.txt
+++ b/pyGHDL/requirements.txt
@@ -1,2 +1,2 @@
 pydecor>=2.0.1
-pyVHDLModel>=0.7.3
+pyVHDLModel>=0.9.0
diff --git a/testsuite/pyunit/SimpleEntity.vhdl b/testsuite/pyunit/SimpleEntity.vhdl
index a61c1cf93..98d0afbb7 100644
--- a/testsuite/pyunit/SimpleEntity.vhdl
+++ b/testsuite/pyunit/SimpleEntity.vhdl
@@ -2,7 +2,7 @@ library ieee;
 use     ieee.std_logic_1164.all;
 use     ieee.numeric_std.all;
 
-entity e1 is
+entity entity_1 is
 	generic (
 		BITS : positive := 8
 	);
@@ -11,9 +11,9 @@ entity e1 is
 	  Reset: in  std_logic;
 	  Q:     out std_logic_vector(BITS - 1 downto 0)
 	);
-end entity e1;
+end entity entity_1;
 
-architecture behav of e1 is
+architecture behav of entity_1 is
 begin
 	process(Clock)
 	begin
diff --git a/testsuite/pyunit/dom/SimpleEntity.py b/testsuite/pyunit/dom/SimpleEntity.py
index 2f65c9813..252032f9e 100644
--- a/testsuite/pyunit/dom/SimpleEntity.py
+++ b/testsuite/pyunit/dom/SimpleEntity.py
@@ -35,7 +35,7 @@ class SimpleEntity(TestCase):
 		design.Documents.append(document)
 
 		self.assertEqual(len(design.Documents[0].Entities), 1)
-		self.assertTrue(design.Documents[0].Entities[0].Name == "e1")
+		self.assertTrue(design.Documents[0].Entities[0].Name == "entity_1")
 
 	def test_Architecture(self):
 		design = Design()
diff --git a/testsuite/pyunit/libghdl/Initialize.py b/testsuite/pyunit/libghdl/Initialize.py
index 0e172f1b8..4d5bb521a 100644
--- a/testsuite/pyunit/libghdl/Initialize.py
+++ b/testsuite/pyunit/libghdl/Initialize.py
@@ -51,7 +51,7 @@ class Instantiate(TestCase):
 
 			if nodes.Get_Kind(libraryUnit) == nodes.Iir_Kind.Entity_Declaration:
 				entityName = self.getIdentifier(libraryUnit)
-				self.assertEqual(entityName, "e1", "expected entity name 'e1', got '{}'".format(entityName))
+				self.assertEqual(entityName, "entity_1", "expected entity name 'e1', got '{}'".format(entityName))
 
 			elif nodes.Get_Kind(libraryUnit) == nodes.Iir_Kind.Architecture_Body:
 				architectureName = self.getIdentifier(libraryUnit)
-- 
cgit v1.2.3