aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/using/pyGHDL/pyutils.rst4
-rw-r--r--pyGHDL/README.md5
-rw-r--r--pyGHDL/__init__.py0
-rw-r--r--pyGHDL/dom/Misc.py3
-rw-r--r--pyGHDL/libghdl/version.py2
-rw-r--r--pyGHDL/requirements.txt (renamed from requirements.txt)0
-rw-r--r--pyGHDL/setup.py44
-rw-r--r--setup.py121
-rw-r--r--testsuite/pyunit/SimplePackage.vhdl21
-rw-r--r--testsuite/pyunit/__init__.py14
-rw-r--r--testsuite/pyunit/dom/SimpleEntity.py8
-rw-r--r--testsuite/pyunit/dom/__init__.py13
-rw-r--r--testsuite/pyunit/libghdl/Initialize.py4
-rw-r--r--testsuite/pyunit/libghdl/__init__.py13
-rw-r--r--testsuite/pyunit/units01/demo.vhdl12
-rw-r--r--testsuite/pyunit/units01/show_ports.py111
-rwxr-xr-xtestsuite/pyunit/units01/show_units.py55
-rwxr-xr-xtestsuite/pyunit/units01/testsuite.sh11
18 files changed, 200 insertions, 241 deletions
diff --git a/doc/using/pyGHDL/pyutils.rst b/doc/using/pyGHDL/pyutils.rst
new file mode 100644
index 000000000..5efe078b8
--- /dev/null
+++ b/doc/using/pyGHDL/pyutils.rst
@@ -0,0 +1,4 @@
+libghdl.pyutils
+===============
+
+.. automodule:: libghdl.pyutils
diff --git a/pyGHDL/README.md b/pyGHDL/README.md
index deb45b8d8..81afcc1cb 100644
--- a/pyGHDL/README.md
+++ b/pyGHDL/README.md
@@ -4,9 +4,8 @@ Python binding for GHDL and high-level APIs.
## Provided Packages
+* `pyGHDL.cli` - Command line interface tools.
+* `pyGHDL.dom` - Document Object Model (DOM) for VHDL parsed by `libghdl`.
* `pyGHDL.libghdl` - Low-level Python bindings to GHDL's `libghdl` shared library.
Auto generated API from Ada sources.
-* `pyGHDL.cli` - Command line interface tools.
* `pyGHDL.lsp` - Language Server Protocol (LSP) implementation for VHDL.
-* `pyGHDL.dom` - Document Object Model (DOM) for VHDL parsed by `libghdl`.
-* `pyGHDL.xtools` - *tbd*
diff --git a/pyGHDL/__init__.py b/pyGHDL/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/pyGHDL/__init__.py
diff --git a/pyGHDL/dom/Misc.py b/pyGHDL/dom/Misc.py
index 82c1f8fac..f8c3d5b73 100644
--- a/pyGHDL/dom/Misc.py
+++ b/pyGHDL/dom/Misc.py
@@ -32,7 +32,8 @@ class Design(VHDLModel_Design):
errorout_console.Install_Handler()
libghdl.set_option(b"--std=08")
- libghdl.analyze_init()
+# if libghdl.analyze_init_status() != 0:
+# raise LibGHDLException("Error initializing 'libghdl'.")
@export
class Library(VHDLModel_Library):
diff --git a/pyGHDL/libghdl/version.py b/pyGHDL/libghdl/version.py
index fcc6d13d8..6c7936ab3 100644
--- a/pyGHDL/libghdl/version.py
+++ b/pyGHDL/libghdl/version.py
@@ -1 +1 @@
-__version__ = "1.0-dev"
+__version__ = "1.0.0-dev"
diff --git a/requirements.txt b/pyGHDL/requirements.txt
index 6f7932078..6f7932078 100644
--- a/requirements.txt
+++ b/pyGHDL/requirements.txt
diff --git a/pyGHDL/setup.py b/pyGHDL/setup.py
deleted file mode 100644
index b76d8cd29..000000000
--- a/pyGHDL/setup.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python
-
-from setuptools import setup, find_packages
-import re
-
-
-def get_version():
- # Try from version.py. Reads it to avoid loading the shared library.
- r = re.compile('^__version__ = "(.*)"\n')
- try:
- l = open("libghdl/version.py").read()
- m = r.match(l)
- if m:
- return m.group(1)
- except:
- pass
- raise Exception("Cannot find version")
-
-
-# Extract the version now, as setup() may change the current directory.
-version = get_version()
-
-setup(
- name="pyGHDL",
- version=version,
- description="Python bindings for GHDL and high-level APIs (incl. LSP)",
- author="Tristan Gingold",
- author_email="tgingold@free.fr",
- url="http://github.com/ghdl/ghdl",
- license="GPL-2.0-or-later",
- packages=find_packages(),
- # List run-time dependencies here. For an analysis of "install_requires"
- # vs pip's requirements files see:
- # https://packaging.python.org/en/latest/requirements.html
- install_requires=["attrs"],
- # To provide executable scripts, use entry points in preference to the
- # "scripts" keyword. Entry points provide cross-platform support and allow
- # pip to create the appropriate form of executable for the target platform.
- entry_points={
- "console_scripts": [
- "ghdl-ls = vhdl_langserver.main:main",
- ]
- },
-) \ No newline at end of file
diff --git a/setup.py b/setup.py
new file mode 100644
index 000000000..7cbb0009e
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,121 @@
+# EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
+# vim: tabstop=2:shiftwidth=2:noexpandtab
+# kate: tab-width 2; replace-tabs off; indent-width 2;
+# =============================================================================
+# ____ _ _ ____ _
+# _ __ _ _ / ___| | | | _ \| |
+# | '_ \| | | | | _| |_| | | | | |
+# | |_) | |_| | |_| | _ | |_| | |___
+# | .__/ \__, |\____|_| |_|____/|_____|
+# |_| |___/
+# =============================================================================
+# Authors: Tristan Gingold
+# Patrick Lehmann
+#
+# Package installer: Python binding for GHDL and high-level APIs.
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2020 Tristan Gingold
+#
+# GHDL 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, or (at your option) any later
+# version.
+#
+# GHDL 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 GHDL; see the file COPYING. If not, write to the Free
+# Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+#
+from pathlib import Path
+from re import compile as re_compile
+from setuptools import setup as setuptools_setup, find_packages as setuptools_find_packages
+
+gitHubNamespace = "ghdl"
+projectName = "ghdl"
+packageName = "pyGHDL"
+packagePath = Path(packageName)
+
+# Read (local) README for upload to PyPI
+readmeFile = packagePath / "README.md"
+with readmeFile.open("r") as file:
+ long_description = file.read()
+
+# Read requirements file and add them to package dependency list
+requirementsFile = packagePath / "requirements.txt"
+with requirementsFile.open("r") as file:
+ requirements = [line for line in file.readlines()]
+
+def get_version():
+ # Try from version.py. Reads it to avoid loading the shared library.
+ pattern = re_compile('^__version__ = "(.*)"\n')
+ try:
+ line = open("pyGHDL/libghdl/version.py").read()
+ match = pattern.match(line)
+ if match:
+ return match.group(1)
+ except:
+ pass
+
+ raise Exception("Cannot find version")
+
+# Derive URLs
+sourceCodeURL = "https://github.com/{namespace}/{projectName}".format(namespace=gitHubNamespace, projectName=projectName)
+documentationURL = "https://{namespace}.github.io/{projectName}/using/py/index.html".format(namespace=gitHubNamespace, projectName=projectName)
+
+# Assemble all package information
+setuptools_setup(
+ name=packageName,
+ version=get_version(),
+
+ author="Tristan Gingold",
+ author_email="tgingold@free.fr",
+ license="GPL-2.0-or-later",
+ description="Python binding for GHDL and high-level APIs (incl. LSP).",
+ long_description=long_description,
+ long_description_content_type="text/markdown",
+
+ url=sourceCodeURL,
+ project_urls={
+ 'Documentation': documentationURL,
+ 'Source Code': sourceCodeURL,
+ 'Issue Tracker': sourceCodeURL + "/issues"
+ },
+
+ python_requires='>=3.8',
+ install_requires=requirements,
+ packages=setuptools_find_packages(exclude=("tests",)),
+ entry_points={
+ 'console_scripts': [
+ "ghdl-ls = pyGHDL.cli.lsp:main"
+ ]
+ },
+
+ keywords="Python3 VHDL Parser Compiler Simulator GHDL",
+ classifiers=[
+ "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",
+ "Operating System :: MacOS",
+ "Operating System :: Microsoft :: Windows :: Windows 10",
+ "Operating System :: POSIX :: Linux",
+ "Programming Language :: Python :: 3 :: Only",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
+ "Development Status :: 4 - Beta",
+# "Development Status :: 5 - Production/Stable",
+ "Intended Audience :: Developers",
+ "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
+ "Topic :: Software Development :: Code Generators",
+ "Topic :: Software Development :: Compilers",
+ "Topic :: Software Development :: Testing",
+ "Topic :: Utilities",
+ ]
+)
diff --git a/testsuite/pyunit/SimplePackage.vhdl b/testsuite/pyunit/SimplePackage.vhdl
new file mode 100644
index 000000000..f06cc32fa
--- /dev/null
+++ b/testsuite/pyunit/SimplePackage.vhdl
@@ -0,0 +1,21 @@
+library ieee;
+use ieee.numeric_std.all
+
+package pack_1 is
+ constant const_1 : boolean;
+
+ type matrix is array(natural range <>, natural range <>) of std_logic;
+
+ subtype matrix8x8 is matrix(7 downto 0, 7 downto 0);
+
+ function func1(value : unsigned) return natural;
+end package;
+
+package body pack_1 is
+ constant const_1 : boolean := true;
+
+ function func1(value : unsigned) return natural is
+ begin
+ return to_integer(value);
+ end function;
+end package body;
diff --git a/testsuite/pyunit/__init__.py b/testsuite/pyunit/__init__.py
new file mode 100644
index 000000000..eff53eb2f
--- /dev/null
+++ b/testsuite/pyunit/__init__.py
@@ -0,0 +1,14 @@
+from unittest import TestSuite
+
+try:
+ from testsuite.pyunit import libghdl, dom
+except ModuleNotFoundError:
+ from pyunit import libghdl, dom
+
+def load_tests(loader, testCases, pattern):
+ suite = TestSuite()
+
+ suite.addTests(loader.loadTestsFromModule(libghdl))
+ suite.addTests(loader.loadTestsFromModule(dom))
+
+ return suite
diff --git a/testsuite/pyunit/dom/SimpleEntity.py b/testsuite/pyunit/dom/SimpleEntity.py
index 046d5ceff..a8caf9e6f 100644
--- a/testsuite/pyunit/dom/SimpleEntity.py
+++ b/testsuite/pyunit/dom/SimpleEntity.py
@@ -2,7 +2,6 @@ from pathlib import Path
from unittest import TestCase
from pyGHDL.dom.Misc import Design, Library, Document
-from pyGHDL.dom.DesignUnit import Entity, Architecture
if __name__ == "__main__":
@@ -37,3 +36,10 @@ class SimpleEntity(TestCase):
self.assertEqual(len(design.Documents[0].Entities), 1)
self.assertTrue(design.Documents[0].Entities[0].Name == "e1")
+ def test_Architecture(self):
+ design = Design()
+ document = Document(self._path)
+ design.Documents.append(document)
+
+ self.assertEqual(len(design.Documents[0].Architectures), 1)
+ self.assertTrue(design.Documents[0].Architectures[0].Name == "behav")
diff --git a/testsuite/pyunit/dom/__init__.py b/testsuite/pyunit/dom/__init__.py
new file mode 100644
index 000000000..9c103eb6a
--- /dev/null
+++ b/testsuite/pyunit/dom/__init__.py
@@ -0,0 +1,13 @@
+from unittest import TestSuite
+
+try:
+ from testsuite.pyunit.dom import SimpleEntity
+except ModuleNotFoundError:
+ from pyunit.dom import SimpleEntity
+
+def load_tests(loader, testCases, pattern):
+ suite = TestSuite()
+
+ suite.addTests(loader.loadTestsFromModule(SimpleEntity))
+
+ return suite
diff --git a/testsuite/pyunit/libghdl/Initialize.py b/testsuite/pyunit/libghdl/Initialize.py
index 8bbc0e954..fb7196e7c 100644
--- a/testsuite/pyunit/libghdl/Initialize.py
+++ b/testsuite/pyunit/libghdl/Initialize.py
@@ -33,8 +33,8 @@ class Instantiate(TestCase):
libghdl.set_option(b"--std=08")
# Finish initialization. This will load the standard package.
- if libghdl.analyze_init_status() != 0:
- self.fail("libghdl initialization error")
+# if libghdl.analyze_init_status() != 0:
+# self.fail("libghdl initialization error")
# Load the file
file_id = name_table.Get_Identifier(str(self._filename).encode("utf_8"))
diff --git a/testsuite/pyunit/libghdl/__init__.py b/testsuite/pyunit/libghdl/__init__.py
new file mode 100644
index 000000000..4aeab3ec3
--- /dev/null
+++ b/testsuite/pyunit/libghdl/__init__.py
@@ -0,0 +1,13 @@
+from unittest import TestSuite
+
+try:
+ from testsuite.pyunit.libghdl import Initialize
+except ModuleNotFoundError:
+ from pyunit.libghdl import Initialize
+
+def load_tests(loader, testCases, pattern):
+ suite = TestSuite()
+
+ suite.addTests(loader.loadTestsFromModule(Initialize))
+
+ return suite
diff --git a/testsuite/pyunit/units01/demo.vhdl b/testsuite/pyunit/units01/demo.vhdl
deleted file mode 100644
index ed98c936a..000000000
--- a/testsuite/pyunit/units01/demo.vhdl
+++ /dev/null
@@ -1,12 +0,0 @@
-entity e1 is
-port (
- CLK: in std_logic;
- RST: in std_logic;
- Q: out std_logic_vector(7 downto 0)
-);
-end e1;
-
-architecture behav of e1 is
-begin
- assert false report "arch" severity note;
-end behav;
diff --git a/testsuite/pyunit/units01/show_ports.py b/testsuite/pyunit/units01/show_ports.py
deleted file mode 100644
index a11f2acbd..000000000
--- a/testsuite/pyunit/units01/show_ports.py
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env python
-from sys import argv
-from pathlib import Path
-
-import libghdl
-from libghdl.thin import name_table
-from libghdl.thin import files_map
-from libghdl.thin.vhdl import nodes
-from libghdl.thin.vhdl import sem_lib
-from libghdl.thin.vhdl import pyutils
-from libghdl.thin import errorout_console
-
-
-def get_identifier_ptr(n):
- """Return the python string from node :param n: identifier"""
- return name_table.Get_Name_Ptr(nodes.Get_Identifier(n)).decode("utf-8")
-
-
-def get_port_mode(port) -> str:
- """Return the Mode of a port, as a string"""
- mode = nodes.Get_Mode(port)
- return (
- "in"
- if mode == nodes.Iir_Mode.In_Mode
- else "out"
- if mode == nodes.Iir_Mode.Out_Mode
- else "inout"
- if mode == nodes.Iir_Mode.Inout_Mode
- else "buffer"
- if mode == nodes.Iir_Mode.Buffer_Mode
- else "linkage"
- if mode == nodes.Iir_Mode.Linkage_Mode
- else "unknown"
- )
-
-
-def get_port_type(port) -> str:
- "Return the Type of a port, as a string"
- subtype = nodes.Get_Subtype_Indication(port)
- skind = nodes.Get_Kind(subtype)
-
- if skind == nodes.Iir_Kind.Simple_Name:
- return get_identifier_ptr(subtype)
-
- if skind == nodes.Iir_Kind.Array_Subtype_Definition:
- mark = get_identifier_ptr(nodes.Get_Subtype_Type_Mark(subtype))
-
- for rng in pyutils.flist_iter(nodes.Get_Index_Constraint_List(subtype)):
- if nodes.Get_Kind(rng) == nodes.Iir_Kind.Range_Expression:
- return "%s(%d %s %d)" % (
- mark,
- nodes.Get_Value(nodes.Get_Left_Limit_Expr(rng)),
- "downto" if nodes.Get_Direction(rng) else "to",
- nodes.Get_Value(nodes.Get_Right_Limit_Expr(rng)),
- )
- return "UNSUPPORTED array_subtype_definition"
-
- return "UNSUPPORTED"
-
-
-def list_units(filename):
- # Load the file
- file_id = name_table.Get_Identifier(filename.encode("utf_8"))
- sfe = files_map.Read_Source_File(name_table.Null_Identifier, file_id)
- if sfe == files_map.No_Source_File_Entry:
- print("cannot open file '%s'" % filename)
- return
-
- # Parse
- file = sem_lib.Load_File(sfe)
-
- # Display all design units
- unit = nodes.Get_First_Design_Unit(file)
- while unit != nodes.Null_Iir:
- lib_unit = nodes.Get_Library_Unit(unit)
- if nodes.Get_Kind(lib_unit) == nodes.Iir_Kind.Entity_Declaration:
- print(" - entity %s" % get_identifier_ptr(lib_unit))
- for port in pyutils.chain_iter(nodes.Get_Port_Chain(lib_unit)):
- print(
- " * %s %s %s"
- % (
- get_identifier_ptr(port),
- get_port_mode(port),
- get_port_type(port),
- )
- )
- elif nodes.Get_Kind(lib_unit) == nodes.Iir_Kind.Architecture_Body:
- print(
- " - architecture %s of %s"
- % (
- get_identifier_ptr(lib_unit),
- get_identifier_ptr(nodes.Get_Entity_Name(lib_unit)),
- )
- )
- else:
- print("unknown unit!")
- unit = nodes.Get_Chain(unit)
-
-
-if __name__ == "__main__":
- # Initialization: set options and then load libaries
- errorout_console.Install_Handler()
- libghdl.set_option(b"--std=08")
- if libghdl.analyze_init_status() != 0:
- raise Exception("libghdl initialization error")
-
- # Recursively find and parse all the files with extension *.vhdl
- if len(argv) > 1:
- for file in Path(argv[1]).glob("**/*.vhdl"):
- print("ยท %s" % file)
- list_units(str(file))
diff --git a/testsuite/pyunit/units01/show_units.py b/testsuite/pyunit/units01/show_units.py
deleted file mode 100755
index 43baf9aed..000000000
--- a/testsuite/pyunit/units01/show_units.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-import libghdl
-from libghdl.thin import name_table
-from libghdl.thin import files_map
-from libghdl.thin.vhdl import nodes
-from libghdl.thin.vhdl import sem_lib
-from libghdl.thin import errorout_console
-
-
-def init():
- """Initialization: set options and then load libaries"""
- # Print error messages on the console
- errorout_console.Install_Handler()
- # Set options. This must be done before analyze_init()
- libghdl.set_option(b"--std=08")
- # Finish initialization. This will load the standard package
- if libghdl.analyze_init_status() != 0:
- raise Exception("libghdl initialization error")
-
-def get_identifier_ptr(n):
- """Return the python string from node :param n: identifier"""
- return name_table.Get_Name_Ptr(nodes.Get_Identifier(n)).decode("utf-8")
-
-
-def list_units(filename):
- # Load the file
- file_id = name_table.Get_Identifier(filename.encode("utf_8"))
- sfe = files_map.Read_Source_File(name_table.Null_Identifier, file_id)
- if sfe == files_map.No_Source_File_Entry:
- print("cannot open file '%s'" % filename)
- return
-
- # Parse
- file = sem_lib.Load_File(sfe)
-
- # Display all design units
- unit = nodes.Get_First_Design_Unit(file)
- while unit != nodes.Null_Iir:
- lib_unit = nodes.Get_Library_Unit(unit)
- if nodes.Get_Kind(lib_unit) == nodes.Iir_Kind.Entity_Declaration:
- print("entity %s" % get_identifier_ptr(lib_unit))
- elif nodes.Get_Kind(lib_unit) == nodes.Iir_Kind.Architecture_Body:
- print("architecture %s" % get_identifier_ptr(lib_unit))
- else:
- print("unknown unit!")
- unit = nodes.Get_Chain(unit)
-
-
-def main():
- init()
- list_units("demo.vhdl")
-
-
-if __name__ == "__main__":
- main()
diff --git a/testsuite/pyunit/units01/testsuite.sh b/testsuite/pyunit/units01/testsuite.sh
deleted file mode 100755
index f45d12ac3..000000000
--- a/testsuite/pyunit/units01/testsuite.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#! /bin/sh
-
-. ../../testenv.sh
-
-$PYTHON show_units.py
-
-echo ""
-
-$PYTHON show_ports.py ./
-
-echo "Test successful"