Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Makefiles #24

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
5 changes: 5 additions & 0 deletions .github/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM ghdl/vunit:llvm

RUN apt update -qq \
&& apt install -y imagemagick \
&& python3 -m pip install pytest --progress-bar off
120 changes: 52 additions & 68 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,88 +11,72 @@ env:

jobs:

lin:
strategy:
fail-fast: false
max-parallel: 3
matrix:
task: [
vhpidirect/quickstart/random,
vhpidirect/quickstart/math,
vhpidirect/quickstart/customc,
vhpidirect/quickstart/wrapping/basic,
vhpidirect/quickstart/wrapping/time,
vhpidirect/quickstart/linking/bind,
vhpidirect/quickstart/package,
vhpidirect/quickstart/sharedvar,
vhpidirect/shared/shlib,
vhpidirect/shared/dlopen,
vhpidirect/shared/shghdl,
vhpidirect/arrays/intvector,
vhpidirect/arrays/logicvector,
vhpidirect/arrays/matrices,
vhpidirect/arrays/matrices/framebuffer,
vpi/quickstart,
]
lin-docker:
runs-on: ubuntu-latest
env:
DOCKER_BUILDKIT: 1
DOCKER_IMAGE: ghdl/ghdl:buster-llvm-7
steps:
- uses: actions/checkout@v2
- run: docker pull $DOCKER_IMAGE
- run: docker run --rm -tv $(pwd):/src -e CI $DOCKER_IMAGE /src/${{ matrix.task}}/run.sh
- run: docker build -t cosim/test - < .github/Dockerfile
- run: docker run --rm -v $(pwd):/src -w /src -e CI cosim/test python3 -m pytest -v -s -ra test.py --color=yes

vunit:
strategy:
fail-fast: false
max-parallel: 3
matrix:
task: [
vhpidirect/arrays/matrices/vunit_axis_vcs,
]
win-stable:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The failure of this task might be legit. The make that is available in the PATH was not explicitly installed by us. It seems to be preinstalled from Chocolatey. We might investigate if we can make it work (e.g. check_call(['make', 'run'], shell=True, cwd=str(self.vhpidirect / 'arrays' / 'intvector'))) or whether we need to use eine/setup-msys2 here too.

I'd say that v0.37 windows releases of GHDL do require a MINGW environment. However, it has been surprising for me that just extracting the zipfile was working fine until now. Maybe GHDL was picking the MINGW libs of Git for Windows, which is installed by default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad to see it worked. It would have been a pain to fix win-stable otherwise...

runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.8
- env:
WINDOWS_RELEASE: 0.37-mingw64-llvm
shell: bash
run: |
curl -fsSL -o ghdl.zip https://github.com/ghdl/ghdl/releases/download/v0.37/ghdl-${WINDOWS_RELEASE}.zip
7z x ghdl.zip "-o../ghdl-tmp" -y
mv ../ghdl-tmp/GHDL/${WINDOWS_RELEASE}/ ../ghdl
rm -rf ../ghdl-tmp ghdl.zip
export PATH=$PATH:$(pwd)/../ghdl/bin
python -m pip install pytest vunit_hdl --progress-bar off
python -m pytest -v -s -ra test.py --color=yes

lin-setup:
runs-on: ubuntu-latest
env:
DOCKER_BUILDKIT: 1
DOCKER_IMAGE: ghdl/vunit:llvm
steps:
- uses: actions/checkout@v2
- run: docker pull $DOCKER_IMAGE
- run: docker run --rm -tv $(pwd):/src -w /src/${{ matrix.task}} -e CI $DOCKER_IMAGE python3 run.py -v
- uses: umarcor/setup-ghdl@master
with:
backend: llvm
- uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies
run: |
ghdl --version
sudo apt update -qq
sudo apt install -y imagemagick
python -m pip install --progress-bar off pytest vunit_hdl
- run: python -m pytest -v -s -ra test.py --color=yes

win:
strategy:
fail-fast: false
max-parallel: 3
matrix:
task: [
vhpidirect/quickstart/random,
vhpidirect/quickstart/math,
vhpidirect/quickstart/customc,
vhpidirect/quickstart/wrapping/basic,
vhpidirect/quickstart/wrapping/time,
#vhpidirect/quickstart/linking/bind, ! needs investigation, output of list-link seems to have wrong path format
vhpidirect/quickstart/package,
vhpidirect/quickstart/sharedvar,
vhpidirect/shared/shlib,
#vhpidirect/shared/dlopen, ! dlfcn.h is not available on win
#vhpidirect/shared/shghdl, ! dlfcn.h is not available on win
vhpidirect/arrays/intvector,
vhpidirect/arrays/logicvector,
vhpidirect/arrays/matrices,
#vhpidirect/arrays/matrices/framebuffer, ! needs ImageMagick's 'convert'
vpi/quickstart,
]
win-setup:
runs-on: windows-latest
env:
WINDOWS_RELEASE: 0.37-mingw64-llvm
steps:
- uses: actions/checkout@v2
- shell: bash
- uses: eine/setup-msys2@v0
with:
msystem: MINGW64
update: true
install: mingw-w64-x86_64-python-pip make
- uses: umarcor/setup-ghdl@master
with:
backend: llvm
- name: Install dependencies
shell: msys2 {0}
run: |
curl -fsSL -o ghdl.zip https://github.com/ghdl/ghdl/releases/download/v0.37/ghdl-${WINDOWS_RELEASE}.zip
7z x ghdl.zip "-o../ghdl-tmp" -y
mv ../ghdl-tmp/GHDL/${WINDOWS_RELEASE}/ ../ghdl
rm -rf ../ghdl-tmp ghdl.zip
export PATH=$PATH:$(pwd)/../ghdl/bin
./${{ matrix.task}}/run.sh
ghdl --version
python -m pip install --progress-bar off pytest vunit_hdl
- shell: msys2 {0}
run: |
python -m pytest -v -s -ra test.py --color=yes
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ ent*
tb*
!*.vhd
!*.vhdl
doc/_build
.vunit_hash
**/vunit_out/
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,23 @@ Subdirs in [vhpidirect](./vhpidirect) and [vpi](./vpi) contain groups of example
additional examples. Explanations are available in the [docs](https://ghdl.github.io/ghdl-cosim).

*This repository was created recently and multiple existing examples are not published yet. Find on-going work in issue [#1](https://github.com/ghdl/ghdl-cosim/issues/1) and in [open Pull Requests](https://github.com/ghdl/ghdl-cosim/pulls)*.

## Makefiles

### Brief refresher

The first rule in each makefile is the default rule executed, `afresh` will clean and then run. This is triggered by calling `make`.

All makefile rules can be called by specifying the target (argument left of the rule's ':') after make: e.g. `make run`

Make echoes each command before executing it, unless the line starts with `@`. All lines are echoed to the terminal, excepting `echo` calls.
This provides transparency on the commands being executed.

### Symbols used

The symbols below are used in order to make it easy to create a consistent change in the make operation.

- `CC?=gcc`, `CFLAGS+=-fPIC`
- These determine which C compiler is used and the flags that are issued with it.
- `GHDL?=ghdl`, `STD?=93`
- These determine the GHDL executable called and the VHDL standard used.
2 changes: 1 addition & 1 deletion doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ supported. However, a *vhdlator*/*ghdlator* might be available in the future.
because, as the name suggests, it is a direct interface. However, on the one hand VHPIDIRECT requires modification of
VHDL sources, which might not be possible or desirable in certain contexts. On the other hand, VPI/VHPI allow use cases
which are not yet possible with VHPIDIRECT, such as controlling execution time steps. It is suggested to read the quick
start examples of both interfacing mechanisms, in order to get a feel of the differences.
start examples of both interfacing mechanisms, in order to get a feel for the differences.


.. toctree::
Expand Down
11 changes: 7 additions & 4 deletions doc/vhpi/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ Introduction
============

.. ATTENTION::
Since VPI and VHPI provide very similar features, and because VPI is already supported in GHDL, VHPI is not available (yet).
Hence, the information in this section is provided for completeness only.
Since VPI and VHPI provide very similar features, and because VPI is already supported in GHDL, VHPI is not available
(yet). Hence, the information in this section is provided for completeness only.

VHDL Programming Interface (VHPI) was introduced in 2007, as an ammendment to IEEE Std 1076-2002: `1076c-2007 - IEEE Standard VHDL Language Reference Manual - Procedural Language Application Interface <https://ieeexplore.ieee.org/document/4299594>`_.
In the 2009, the programming interface was published as part of `1076-2008 - IEEE Standard VHDL Language Reference Manual <https://ieeexplore.ieee.org/document/4772740>`_.
The latest version was published in 2019: `1076-2019 - IEEE Standard for VHDL Language Reference Manual <https://ieeexplore.ieee.org/document/8938196>`_.

Some vendors support C programming interfaces similar to VHPI. For example, Mentor Graphics' ModelSim/QuestaSim supports a
Foreign Language Interface (FLI) that provides functions to have procedural access to information within the simulator, ``vsim``. These allow to traverse the hierarchy, get/set values and control a simulation run. See `Using ModelSim Foreign Language Interface for c – VHDL CoSimulation and for Simulator Control on Linux x86 Platform <https://opencores.org/usercontent/doc/1380917197>`_ and `github.com/andrepool/fli <https://github.com/andrepool/fli>`_.
Some vendors support C programming interfaces similar to VHPI. For example, Mentor Graphics' ModelSim/QuestaSim supports
a Foreign Language Interface (FLI) that provides functions to have procedural access to information within the simulator,
``vsim``. These functions allow traversing the hierarchy, getting/setting values and controlling a simulation run. See
`Using ModelSim Foreign Language Interface for c – VHDL CoSimulation and for Simulator Control on Linux x86 Platform <https://opencores.org/usercontent/doc/1380917197>`_
and `github.com/andrepool/fli <https://github.com/andrepool/fli>`_.
16 changes: 8 additions & 8 deletions doc/vhpidirect/examples/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ Wrapping ghdl_main
:cosimtree:`basic <vhpidirect/quickstart/wrapping/basic>`
---------------------------------------------------------

Instead of using GHDL's own entrypoint to the execution, it is possible to wrap it by providing a custom ``main``
function. Upon existence of ``main``, execution of the simulation is triggered by calling ``ghdl_main``.
Instead of using GHDL's own entrypoint to the execution, it is possible to wrap it by providing a custom program
entrypoint (``main`` function), wherein the execution of the simulation is triggered by calling ``ghdl_main``.

This is the most basic example of such usage. ``ghdl_main`` is declared as ``extern`` in C, and arguments ``argc`` and
``argv`` are passed without modification. However, this sets the ground for custom prepocessing and postprocessing in a
foreign language.
This example shows the most basic of such usage. ``ghdl_main`` is declared as ``extern`` in C, and arguments ``argc``
and ``argv`` are passed without modification. However, this sets the ground for custom prepocessing and postprocessing
in a foreign language.

Other options are to just pass empty arguments (``ghdl_main(0, NULL)``) or to customize them:

Expand All @@ -84,11 +84,11 @@ See :ref:`COSIM:VHPIDIRECT:Wrapping` for further details about the constraints o
-------------------------------------------------------

Although most of the provided examples are written in C, VHPIDIRECT can be used with any language that supports a
C-alike compile and link model.
C-like compile and link model.

This example shows how to time the execution of a simulation from either C or Ada. In both cases, function ``clock`` is
used to get the time before and after calling ``ghdl_main``. Regarding the build procedure, it is to be noted that C
sources are elaborated with :option:`-e`, because GHDL allows to pass parameters (in this case, additional C sources)
sources are elaborated with :option:`-e`, because GHDL allows passing parameters (in this case, additional C sources)
to the compiler and/or linker. However, since it is not possible to do so with Ada, ``gnatmake``, :option:`--bind` and
:option:`--list-link` are used instead. See :ref:`COSIM:VHPIDIRECT:Linking` for further info about custom linking setups.

Expand Down Expand Up @@ -137,7 +137,7 @@ numbers. Subprogram declaration requirements are detailed under the :ref:`COSIM:
While sharing variables through packages in VHDL 1993 is flexible, in VHDL 2008 protected types need to be used.
However, GHDL allows to relax some rules of the LRM through :option:`-frelaxed`.

This example shows multiple alternatives to share variables through packages, depending on the target version of the
This example showcases multiple ways of sharing variables through packages, depending on the target version of the
standard. Three different binaries are built from the same entity, using:

* A VHDL 1993 package with ``--std=93``.
Expand Down
2 changes: 1 addition & 1 deletion doc/vpi/examples/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Examples
########

A very brief description of how to use VPI is that ``vpi_user.h`` provides dozens of functions to scan/navigate the hierarchy
of the elaborated hardware design, and it allows to set callbacks for specific events/signals.
of the elaborated hardware design, and it allows setting callbacks for specific events/signals.

.. NOTE::
Since VHDL sources are agnostic to the usage of VPI modules, most of the examples in this section reuse the same VHDL
Expand Down
2 changes: 1 addition & 1 deletion doc/vpi/examples/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ Quick Start
This is the most minimal example, where a single callback is registered at the beginning of the simulation. The callback just
prints ``Hello!``. Then, the simulation is executed as usual.

VPI allows to register callbacks at multiple events and to optionally delay their execution after the event is triggered.
VPI allows registering callbacks at multiple events and to optionally delay their execution after the event is triggered.
The list of available callback reasons is defined in :ghdlsrc:`vpi_user.h <grt/vpi_user.h>`. The structure type that is used
and required to register a callback, ``s_cb_data``, is also defined in the same header file.
92 changes: 92 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
"""
Verify that all example run scripts work correctly
"""

from sys import executable, platform
from os import environ
from pathlib import Path
from subprocess import check_call
import unittest
import pytest


class TestExamples(unittest.TestCase):
"""
Verify that example run scripts work correctly
"""

def setUp(self):
self.shell = ['bash'] if platform == 'win32' else []
self.root = Path(__file__).parent
self.vhpidirect = self.root / 'vhpidirect'
self.vpi = self.root / 'vpi'

def test_vhpidirect_quickstart_random(self):
check_call(self.shell + [str(self.vhpidirect / 'quickstart' / 'random' / 'run.sh')], shell=True)

def test_vhpidirect_quickstart_math(self):
check_call(self.shell + [str(self.vhpidirect / 'quickstart' / 'math' / 'run.sh')], shell=True)

def test_vhpidirect_quickstart_customc(self):
check_call(self.shell + [str(self.vhpidirect / 'quickstart' / 'customc' / 'run.sh')], shell=True)

def test_vhpidirect_quickstart_wrapping_basic(self):
check_call(self.shell + [str(self.vhpidirect / 'quickstart' / 'wrapping' / 'basic' / 'run.sh')], shell=True)

def test_vhpidirect_quickstart_wrapping_time(self):
check_call(self.shell + [str(self.vhpidirect / 'quickstart' / 'wrapping' / 'time' / 'run.sh')], shell=True)

@unittest.skipUnless(
platform != 'win32',
"win: needs investigation, output of list-link seems to have wrong path format",
)
def test_vhpidirect_quickstart_linking_bind(self):
check_call(self.shell + [str(self.vhpidirect / 'quickstart' / 'linking' / 'bind' / 'run.sh')], shell=True)

def test_vhpidirect_quickstart_package(self):
check_call(self.shell + [str(self.vhpidirect / 'quickstart' / 'package' / 'run.sh')], shell=True)

def test_vhpidirect_quickstart_sharedvar(self):
check_call(self.shell + [str(self.vhpidirect / 'quickstart' / 'sharedvar' / 'run.sh')], shell=True)

def test_vhpidirect_shared_shlib(self):
check_call(self.shell + [str(self.vhpidirect / 'shared' / 'shlib' / 'run.sh')], shell=True)

@unittest.skipUnless(
platform != 'win32',
"win: dlfcn.h is not available on win",
)
def test_vhpidirect_shared_dlopen(self):
check_call(self.shell + [str(self.vhpidirect / 'shared' / 'dlopen' / 'run.sh')], shell=True)

@unittest.skipUnless(
platform != 'win32',
"win: dlfcn.h is not available on win",
)
def test_vhpidirect_shared_shghdl(self):
check_call(self.shell + [str(self.vhpidirect / 'shared' / 'shghdl' / 'run.sh')], shell=True)

def test_vhpidirect_arrays_intvector(self):
# check_call(self.shell + [str(self.vhpidirect / 'arrays' / 'intvector' / 'run.sh')], shell=True)
# check_call(self.shell + ['make', 'run'], shell=True, cwd=str(self.vhpidirect / 'arrays' / 'intvector'))
check_call(['make', 'run'], shell=True, cwd=str(self.vhpidirect / 'arrays' / 'intvector'))


def test_vhpidirect_arrays_logicvector(self):
check_call(self.shell + [str(self.vhpidirect / 'arrays' / 'logicvector' / 'run.sh')], shell=True)

def test_vhpidirect_arrays_matrices(self):
check_call(self.shell + [str(self.vhpidirect / 'arrays' / 'matrices' / 'run.sh')], shell=True)

def test_vhpidirect_arrays_matrices_vunit_axis_vcs(self):
check_call([executable, str(self.vhpidirect / 'arrays' / 'matrices' / 'vunit_axis_vcs' / 'run.py')], shell=True)

@unittest.skipUnless(
platform != 'win32',
"win: needs ImageMagick's 'convert'",
)
def test_vhpidirect_arrays_matrices_framebuffer(self):
check_call(self.shell + [str(self.vhpidirect / 'arrays' / 'matrices' / 'framebuffer' / 'run.sh')], shell=True)

def test_vpi_quickstart(self):
check_call(self.shell + [str(self.vpi / 'quickstart' / 'run.sh')], shell=True)
Loading