Skip to content

Commit 00b6b1e

Browse files
committed
vpi: add 'quickstart'
1 parent a7bbd9e commit 00b6b1e

File tree

7 files changed

+152
-3
lines changed

7 files changed

+152
-3
lines changed

.github/workflows/test.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ jobs:
3131
vhpidirect/arrays/intvector,
3232
vhpidirect/arrays/logicvector,
3333
vhpidirect/arrays/matrices,
34+
vpi/quickstart,
3435
]
3536
runs-on: ubuntu-latest
3637
env:
@@ -73,11 +74,12 @@ jobs:
7374
vhpidirect/quickstart/package,
7475
vhpidirect/quickstart/sharedvar,
7576
vhpidirect/shared/shlib,
76-
#vhpidirect/shared/dlopen, ! dlfcn.h is not available on win
77-
#vhpidirect/shared/shghdl, ! dlfcn.h is not available on win
77+
#vhpidirect/shared/dlopen, ! dlfcn.h is not available on win
78+
#vhpidirect/shared/shghdl, ! dlfcn.h is not available on win
7879
vhpidirect/arrays/intvector,
7980
vhpidirect/arrays/logicvector,
8081
vhpidirect/arrays/matrices,
82+
vpi/quickstart,
8183
]
8284
runs-on: windows-latest
8385
env:

doc/vpi/examples/index.rst

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
1+
.. program:: ghdl
2+
.. _COSIM:VPI:Examples:
3+
14
Examples
25
########
36

4-
TBC
7+
A very brief description of how to use VPI is that ``vpi_user.h`` provides dozens of functions to scan/navigate the hierarchy
8+
of the elaborated hardware design, and it allows to set callbacks for specific events/signals.
9+
10+
.. NOTE::
11+
Since VHDL sources are agnostic to the usage of VPI modules, most of the examples in this section reuse the same VHDL
12+
sources. Readers should focus on the differences between the provided C files.
13+
14+
.. ATTENTION::
15+
On Windows, the directory containing ``libghdlvpi.dll`` needs to be added to the ``PATH``. This can be achieved with
16+
:option:`--vpi-library-dir`, :option:`--vpi-library-dir-unix` or ``$(cd $(dirname $(which ghdl))/../lib; pwd)``.
17+
18+
.. toctree::
19+
20+
quickstart

doc/vpi/examples/quickstart.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.. program:: ghdl
2+
.. _COSIM:VPI:Examples:quickstart:
3+
4+
Quick Start
5+
###########
6+
7+
.. _COSIM:VPI:Examples:quickstart:hello:
8+
9+
:cosimtree:`hello <vpi/quickstart/vpi_hello.c>`
10+
***********************************************
11+
12+
This is the most minimal example, where a single callback is registered at the beginning of the simulation. The callback just
13+
prints ``Hello!``. Then, the simulation is executed as usual.
14+
15+
VPI allows to register callbacks at multiple events and to optionally delay their execution after the event is triggered.
16+
The list of available callback reasons is defined in :ghdlsrc:`vpi_user.h <grt/vpi_user.h>`. The structure type that is used
17+
and required to register a callback, ``s_cb_data``, is also defined in the same header file.

vpi/ent.vhd

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
library ieee;
2+
use ieee.std_logic_1164.all;
3+
use ieee.numeric_std.all;
4+
5+
entity ent is
6+
generic (
7+
G_WIDTH : natural := 4
8+
);
9+
port (
10+
A : in std_logic_vector(G_WIDTH-1 downto 0);
11+
B : in std_logic_vector(G_WIDTH-1 downto 0);
12+
C : in std_logic;
13+
Q : out std_logic_vector(G_WIDTH downto 0)
14+
);
15+
end entity;
16+
17+
architecture arch of ent is
18+
19+
signal c_in : unsigned(0 downto 0);
20+
21+
begin
22+
23+
c_in <= to_unsigned(1,1) when C='1' else to_unsigned(0,1);
24+
Q <= std_logic_vector(unsigned('0' & A) + unsigned(B) + c_in);
25+
26+
end architecture;

vpi/quickstart/run.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env sh
2+
3+
set -e
4+
5+
cd $(dirname "$0")
6+
7+
echo "> Analyze ent.vhd and tb.vhd"
8+
ghdl -a ../ent.vhd ../tb.vhd
9+
10+
echo "> Elaborate tb"
11+
ghdl -e -o tb tb
12+
13+
echo "> Compile vpi_hello.c"
14+
ghdl --vpi-compile gcc -c vpi_hello.c -o vpi.o
15+
16+
echo "> Link vpi.o"
17+
ghdl --vpi-link gcc vpi.o -o vpi.vpi
18+
19+
if [ "$OS" = "Windows_NT" ]; then
20+
# Need to put the directory containing libghdlvpi.dll in the path.
21+
PATH=$PATH:`ghdl --vpi-library-dir-unix`
22+
fi
23+
24+
echo "> Execute tb"
25+
./tb --vpi=./vpi.vpi

vpi/quickstart/vpi_hello.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <vpi_user.h>
2+
#include <stdio.h>
3+
4+
PLI_INT32 cb_hello(){
5+
printf("Hello!\n");
6+
return 0;
7+
}
8+
9+
void entry_point_cb() {
10+
s_cb_data cb;
11+
12+
cb.reason = cbStartOfSimulation;
13+
cb.cb_rtn = &cb_hello;
14+
cb.user_data = NULL;
15+
16+
if (vpi_register_cb(&cb) == NULL) {
17+
vpi_printf ("cannot register cbStartOfSimulation call back\n");
18+
}
19+
}
20+
21+
// List of entry points called when the plugin is loaded
22+
void (*vlog_startup_routines[]) () = {entry_point_cb, 0};

vpi/tb.vhd

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
library ieee;
2+
use ieee.std_logic_1164.all;
3+
use ieee.numeric_std.all;
4+
5+
entity tb is
6+
generic (
7+
G_WIDTH : natural := 4;
8+
G_INST : natural := 4
9+
);
10+
end tb;
11+
12+
architecture arch of tb is
13+
14+
signal a, b : std_logic_vector(G_INST*G_WIDTH-1 downto 0);
15+
signal c : std_logic_vector(G_INST downto 0);
16+
17+
begin
18+
19+
i_ent: for x in 0 to G_INST-1 generate
20+
signal q: std_logic_vector(G_WIDTH downto 0);
21+
begin
22+
w_ent: entity work.ent
23+
port map (
24+
A => a((x+1)*G_WIDTH-1 downto x*G_WIDTH),
25+
B => b((x+1)*G_WIDTH-1 downto x*G_WIDTH),
26+
C => c(x),
27+
Q => q
28+
);
29+
c(x+1) <= q(q'left);
30+
end generate;
31+
32+
process
33+
begin
34+
a <= std_logic_vector(to_unsigned(2, a'length));
35+
b <= std_logic_vector(to_unsigned(13, b'length));
36+
c(0) <= '0';
37+
wait for 10 ns;
38+
wait;
39+
end process;
40+
41+
end architecture;

0 commit comments

Comments
 (0)