diff options
-rw-r--r-- | doc/using/pyGHDL/pyutils.rst | 4 | ||||
-rw-r--r-- | pyGHDL/README.md | 5 | ||||
-rw-r--r-- | pyGHDL/__init__.py | 0 | ||||
-rw-r--r-- | pyGHDL/dom/Misc.py | 3 | ||||
-rw-r--r-- | pyGHDL/libghdl/version.py | 2 | ||||
-rw-r--r-- | pyGHDL/requirements.txt (renamed from requirements.txt) | 0 | ||||
-rw-r--r-- | pyGHDL/setup.py | 44 | ||||
-rw-r--r-- | setup.py | 121 | ||||
-rw-r--r-- | testsuite/pyunit/SimplePackage.vhdl | 21 | ||||
-rw-r--r-- | testsuite/pyunit/__init__.py | 14 | ||||
-rw-r--r-- | testsuite/pyunit/dom/SimpleEntity.py | 8 | ||||
-rw-r--r-- | testsuite/pyunit/dom/__init__.py | 13 | ||||
-rw-r--r-- | testsuite/pyunit/libghdl/Initialize.py | 4 | ||||
-rw-r--r-- | testsuite/pyunit/libghdl/__init__.py | 13 | ||||
-rw-r--r-- | testsuite/pyunit/units01/demo.vhdl | 12 | ||||
-rw-r--r-- | testsuite/pyunit/units01/show_ports.py | 111 | ||||
-rwxr-xr-x | testsuite/pyunit/units01/show_units.py | 55 | ||||
-rwxr-xr-x | testsuite/pyunit/units01/testsuite.sh | 11 |
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" |