From 00b6b1e0b0b070863b2d729ddea1a440df07ab4f Mon Sep 17 00:00:00 2001 From: umarcor Date: Sat, 2 May 2020 13:59:43 +0200 Subject: [PATCH] vpi: add 'quickstart' --- .github/workflows/test.yml | 6 +++-- doc/vpi/examples/index.rst | 18 ++++++++++++++- doc/vpi/examples/quickstart.rst | 17 ++++++++++++++ vpi/ent.vhd | 26 +++++++++++++++++++++ vpi/quickstart/run.sh | 25 ++++++++++++++++++++ vpi/quickstart/vpi_hello.c | 22 ++++++++++++++++++ vpi/tb.vhd | 41 +++++++++++++++++++++++++++++++++ 7 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 doc/vpi/examples/quickstart.rst create mode 100644 vpi/ent.vhd create mode 100755 vpi/quickstart/run.sh create mode 100644 vpi/quickstart/vpi_hello.c create mode 100644 vpi/tb.vhd diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 744106ad..8b415fe7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,6 +31,7 @@ jobs: vhpidirect/arrays/intvector, vhpidirect/arrays/logicvector, vhpidirect/arrays/matrices, + vpi/quickstart, ] runs-on: ubuntu-latest env: @@ -73,11 +74,12 @@ jobs: 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/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, + vpi/quickstart, ] runs-on: windows-latest env: diff --git a/doc/vpi/examples/index.rst b/doc/vpi/examples/index.rst index df8af1ba..c4b4abbd 100644 --- a/doc/vpi/examples/index.rst +++ b/doc/vpi/examples/index.rst @@ -1,4 +1,20 @@ +.. program:: ghdl +.. _COSIM:VPI:Examples: + Examples ######## -TBC +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. + +.. NOTE:: + Since VHDL sources are agnostic to the usage of VPI modules, most of the examples in this section reuse the same VHDL + sources. Readers should focus on the differences between the provided C files. + +.. ATTENTION:: + On Windows, the directory containing ``libghdlvpi.dll`` needs to be added to the ``PATH``. This can be achieved with + :option:`--vpi-library-dir`, :option:`--vpi-library-dir-unix` or ``$(cd $(dirname $(which ghdl))/../lib; pwd)``. + +.. toctree:: + + quickstart diff --git a/doc/vpi/examples/quickstart.rst b/doc/vpi/examples/quickstart.rst new file mode 100644 index 00000000..d65ee146 --- /dev/null +++ b/doc/vpi/examples/quickstart.rst @@ -0,0 +1,17 @@ +.. program:: ghdl +.. _COSIM:VPI:Examples:quickstart: + +Quick Start +########### + +.. _COSIM:VPI:Examples:quickstart:hello: + +:cosimtree:`hello ` +*********************************************** + +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. +The list of available callback reasons is defined in :ghdlsrc:`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. diff --git a/vpi/ent.vhd b/vpi/ent.vhd new file mode 100644 index 00000000..185af825 --- /dev/null +++ b/vpi/ent.vhd @@ -0,0 +1,26 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity ent is + generic ( + G_WIDTH : natural := 4 + ); + port ( + A : in std_logic_vector(G_WIDTH-1 downto 0); + B : in std_logic_vector(G_WIDTH-1 downto 0); + C : in std_logic; + Q : out std_logic_vector(G_WIDTH downto 0) + ); +end entity; + +architecture arch of ent is + + signal c_in : unsigned(0 downto 0); + +begin + + c_in <= to_unsigned(1,1) when C='1' else to_unsigned(0,1); + Q <= std_logic_vector(unsigned('0' & A) + unsigned(B) + c_in); + +end architecture; diff --git a/vpi/quickstart/run.sh b/vpi/quickstart/run.sh new file mode 100755 index 00000000..e3485a46 --- /dev/null +++ b/vpi/quickstart/run.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env sh + +set -e + +cd $(dirname "$0") + +echo "> Analyze ent.vhd and tb.vhd" +ghdl -a ../ent.vhd ../tb.vhd + +echo "> Elaborate tb" +ghdl -e -o tb tb + +echo "> Compile vpi_hello.c" +ghdl --vpi-compile gcc -c vpi_hello.c -o vpi.o + +echo "> Link vpi.o" +ghdl --vpi-link gcc vpi.o -o vpi.vpi + +if [ "$OS" = "Windows_NT" ]; then + # Need to put the directory containing libghdlvpi.dll in the path. + PATH=$PATH:`ghdl --vpi-library-dir-unix` +fi + +echo "> Execute tb" +./tb --vpi=./vpi.vpi diff --git a/vpi/quickstart/vpi_hello.c b/vpi/quickstart/vpi_hello.c new file mode 100644 index 00000000..20a61553 --- /dev/null +++ b/vpi/quickstart/vpi_hello.c @@ -0,0 +1,22 @@ +#include +#include + +PLI_INT32 cb_hello(){ + printf("Hello!\n"); + return 0; +} + +void entry_point_cb() { + s_cb_data cb; + + cb.reason = cbStartOfSimulation; + cb.cb_rtn = &cb_hello; + cb.user_data = NULL; + + if (vpi_register_cb(&cb) == NULL) { + vpi_printf ("cannot register cbStartOfSimulation call back\n"); + } +} + +// List of entry points called when the plugin is loaded +void (*vlog_startup_routines[]) () = {entry_point_cb, 0}; diff --git a/vpi/tb.vhd b/vpi/tb.vhd new file mode 100644 index 00000000..68b14a13 --- /dev/null +++ b/vpi/tb.vhd @@ -0,0 +1,41 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity tb is + generic ( + G_WIDTH : natural := 4; + G_INST : natural := 4 + ); +end tb; + +architecture arch of tb is + + signal a, b : std_logic_vector(G_INST*G_WIDTH-1 downto 0); + signal c : std_logic_vector(G_INST downto 0); + +begin + + i_ent: for x in 0 to G_INST-1 generate + signal q: std_logic_vector(G_WIDTH downto 0); + begin + w_ent: entity work.ent + port map ( + A => a((x+1)*G_WIDTH-1 downto x*G_WIDTH), + B => b((x+1)*G_WIDTH-1 downto x*G_WIDTH), + C => c(x), + Q => q + ); + c(x+1) <= q(q'left); + end generate; + + process + begin + a <= std_logic_vector(to_unsigned(2, a'length)); + b <= std_logic_vector(to_unsigned(13, b'length)); + c(0) <= '0'; + wait for 10 ns; + wait; + end process; + +end architecture;