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

VHPIDIRECT, HDL_LOGIC_STATE/CHAR, C access example, #1

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
5e9007c
Update Foreign.rst to reflect my learnings
Apr 5, 2020
23cae01
Update Foreign.rst to reflect my learnings: Rev1
Apr 6, 2020
f01cb36
Add reference-able label to --elab-run
Apr 6, 2020
914585b
Update Foreign.rst to reflect my learnings: Rev2
Apr 6, 2020
9028b5f
Update Foreign.rst to reflect my learnings: Rev3
Apr 6, 2020
ac2eff9
Update Foreign.rst to reflect my learnings: Rev4
Apr 6, 2020
0a208c1
Examples link to systemc-fosdem16 and hwd-ide
Apr 7, 2020
4cd7c00
Reference-able label of Foreign declarations
Apr 7, 2020
7e98cc2
Caccess Example added.
Apr 7, 2020
86fb725
Revise c_access README.rst
Apr 7, 2020
63193c2
Fix .vhd literal includes
Apr 7, 2020
bb33ea0
Another fix for .vhd file include -_-
Apr 7, 2020
9866458
Grammar fix is->are
Apr 7, 2020
cdb33da
Add tip for passing GHDL_main() runtime options
Apr 7, 2020
15e6d9e
Fix Quickstart reference
Apr 7, 2020
82b586e
Add use case of -frelaxed-rules
Apr 7, 2020
8d0ac86
doc: add VHPIDIRECT demo
umarcor Dec 11, 2019
0422e6e
Merge branch 'eg-vhpidirect' of https://github.com/umarcor/ghdl into …
Apr 8, 2020
690bb34
Merge branch 'umarcor-eg-vhpidirect' into c-access-example-doc
Apr 8, 2020
c895453
HDL_LOGIC_STATE/CHAR appended
Apr 8, 2020
76dcc94
testCinterface with v_logic v_ulogic use ieee
Apr 8, 2020
12ab362
c getLogicIntValue, and tb assert to confirm enum
Apr 8, 2020
e8e5745
clean compilation warnings
Apr 8, 2020
2c9aadb
Revert changes to using/* documentation
Apr 8, 2020
48dba5b
Examples page: Clean up single entry toctree
Apr 8, 2020
fd6cfb9
Move cAccess VHPI example to VHPIDIRECT
Apr 8, 2020
8aba8d2
VHPIDIRECT func/var not only in packages.
Apr 8, 2020
92dd40b
label foreign_declarations
Apr 8, 2020
3355535
Fixed ghdlFromArray, added helper ghdlSetRange
Apr 8, 2020
7c6379c
Handle and test 2D int array
Apr 8, 2020
579fd30
Handle and test 3D int arrays.
Apr 8, 2020
17604fc
Fix tests for 2D and 3D
Apr 8, 2020
8b4cace
Re: Collapse 2D/3D to ghdl_NaturalDimArr_t.
Apr 8, 2020
83b25ae
Make ghdl_NaturalDimArr_t dimensions boundless
Apr 8, 2020
f287b53
Remove quick_start reference from VHPIDIRECT
Apr 8, 2020
b05b832
printUnconstrained -> printAttributes
Apr 8, 2020
e63ac0f
Free malloc'd C Pointers: valgrind confirmation
Apr 9, 2020
b6ac9a7
Handle second call getLine/String, no valgrind
Apr 9, 2020
eeb1d6b
Merge remote-tracking branch 'origin/master' into c-access-example-doc
Apr 11, 2020
3c99b5b
Label .. _foreign_declarations:
Apr 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions doc/examples/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
Examples
########

This sections contains advanced examples using specific features of the language, the tool,
or interaction with third-party projects. It is suggested for users who are new to either
`GHDL` or `VHDL` to read :ref:`USING:QuickStart` first.
It is suggested for users who are new to either `GHDL` or `VHDL` to read :ref:`USING:QuickStart` first.

.. toctree::

../examples/VHPIDIRECT
Then :ref:`Examples:VHPIDIRECT` contains advanced examples using specific features of the language, the tool,
or interaction with third-party projects.
3 changes: 2 additions & 1 deletion doc/examples/quick_start/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ The following tips might be useful:

* Use :option:`--ieee=synopsys <--ieee>` if your design depends on a non-standard implementation of the IEEE library.

* Use :option:`-fexplicit` and :option:`-frelaxed-rules` if needed.
* Use :option:`-fexplicit` and :option:`-frelaxed-rules` if needed. For instance when relaxing VHDL 2008's need for shared
variables to be protected types, you can use `--std=08 -frelaxed`.

* Use :option:`--work=LIB_NAME <--work>` to analyze files into the ``LIB_NAME`` library.
To use files analyzed to a different directory, give the path
Expand Down
66 changes: 66 additions & 0 deletions doc/examples/vhpidirect/Caccess/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
.. program:: ghdl
.. _VHPIDIRECT_Example:C_Access:

`C Access` example
=====================

The files
---------

The VHPIDIRECT method of accessing C-side variables and functions from VHDL requires these variables and functions to be declared
with the `foreign` attribute a certain way. It is set to highlight that the function has a foreign C-side definition, as per
:ref:`foreign_declarations`.

The foreign functions can be declared HDL-side in a package as follows, or the declarative part of an architecture (as in :ref:`Examples:VHPIDIRECT:Demo`).
The difference being the scope of the declarations.

This example starts with :file:`c_access.vhdl`:

.. literalinclude:: cAccess.vhd
:language: vhdl

Assuming, for now, that these foreign functions perform as their names indicate they should, the toplevel test bench is defined next (:file:`toplevel.vhdl`):

.. literalinclude:: toplevel.vhd
:language: vhdl

Perhaps this example's flow is clearer by now: the testbench will use an integer array from C, the size of which is defined in C.
It will use a C-side function to prompt the user to set the value for index zero and then print and adjust all of the other indices.
Then the user is prompted to conclude the simulation or repeat the process.


The C functions and variables that GHDL accesses are kept in a separate header/code pair. :file:`cSharedVar.h`:

.. literalinclude:: cSharedVar.h
:language: c

And :file:`cSharedVar.c`:

.. literalinclude:: cSharedVar.c
:language: c


These are also exposed to the custom entry point in :file:`main.c`:

.. literalinclude:: main.c
:language: c

It is seen that the array's length is established, and its contents filled with square numbers, before the GHDL simulation happens.
After that, the array is read out.

.. TIP::
To pass GHDL runtime options, see the second hint under :ref:`Starting_a_simulation_from_a_foreign_program`.

Compilation
-----------

- Firstly, the HDL files must be analysed by GHDL, producing object files for each (:ref:`Analysis:command`).
- Before the elaboration step, the object files of all `.c` files being used are needed, so compile each with `gcc -c main.c -o main.o`.
- Elaborate with each C-side object file and finally the name of the toplevel entity. See :ref:`Starting_a_simulation_from_a_foreign_program` and :ref:`Linking_with_foreign_object_files`.
- The elaboration step is only possible with a GCC or LLVM backend. See :ref:`Elaboration:command`.
- Execute the produced executable.

The compilation steps should look something like :file:`build.sh`:

.. literalinclude:: build.sh
:language: sh
6 changes: 6 additions & 0 deletions doc/examples/vhpidirect/Caccess/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
gcc -c cSharedVar.c -o cSharedVar.o &&
gcc -c main.c -o main.o &&
ghdl-llvm -a cAccess.vhd toplevel.vhd &&
ghdl-llvm -e -Wl,main.o -Wl,cSharedVar.o toplevel
./toplevel
rm *.o work-obj*.cf toplevel
63 changes: 63 additions & 0 deletions doc/examples/vhpidirect/Caccess/cAccess.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
library ieee;
use ieee.std_logic_1164.all;

package cAccess is

type int_ptr is access integer; -- represented C-side with int
function c_intArrSize_ptr return int_ptr; -- represented C-side with int*
attribute foreign of c_intArrSize_ptr :
function is "VHPIDIRECT getIntArrSize"; -- getIntArrSize is the C-side function name

shared variable c_sizeInt : int_ptr := c_intArrSize_ptr;

type int_arr is array(0 to c_sizeInt.all-1) of integer;
type int_arr_ptr is access int_arr; -- represented C-side with int*


function c_intArr_ptr return int_arr_ptr;
attribute foreign of c_intArr_ptr :
function is "VHPIDIRECT getIntArr_ptr";
procedure c_promptIndexValue(index: integer);
attribute foreign of c_promptIndexValue :
procedure is "VHPIDIRECT promptIndexValue";

shared variable c_intArr : int_arr_ptr := c_intArr_ptr;

type char_ptr is access std_ulogic; -- represented C-side with char
function c_finished_ptr return char_ptr;
attribute foreign of c_finished_ptr :
function is "VHPIDIRECT getFinished_ptr";

procedure c_promptFinished;
attribute foreign of c_promptFinished :
procedure is "VHPIDIRECT promptFinished";

shared variable c_finished : char_ptr := c_finished_ptr;
end package cAccess;

package body cAccess is

function c_intArrSize_ptr return int_ptr is
begin
assert false report "c_intArrSize_ptr VHPI" severity failure;
end c_intArrSize_ptr;


function c_intArr_ptr return int_arr_ptr is
begin
assert false report "c_intArr_ptr VHPI" severity failure;
end c_intArr_ptr;
procedure c_promptIndexValue(index: integer) is
begin
assert false report "c_promptIndexValue VHPI" severity failure;
end c_promptIndexValue;

function c_finished_ptr return char_ptr is
begin
assert false report "c_finished_ptr VHPI" severity failure;
end c_finished_ptr;
procedure c_promptFinished is
begin
assert false report "c_promptFinished VHPI" severity failure;
end c_promptFinished;
end package body cAccess;
37 changes: 37 additions & 0 deletions doc/examples/vhpidirect/Caccess/cSharedVar.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "cSharedVar.h"

int* getIntArrSize(){
return &sizeInt;
}

int* getIntArr_ptr(){
return intArray;
}

void promptIndexValue(int index){
char strIn[8];

printf("Enter a number for index %d: ", index);
fgets(strIn, sizeof strIn, stdin);
printf("\n");
sscanf(strIn, "%d", &intArray[index]);
}


char* getFinished_ptr(){
return &finishedChar;
}

void promptFinished(){
char strIn[3];

printf("Conclude simulation? (Y/n): ");
fgets(strIn, sizeof strIn, stdin);
printf("\n");
if(strIn[0] == 'N' || strIn[0] == 'n'){
finishedChar = VHDL_0;
}
else{
finishedChar = VHDL_1;
}
}
26 changes: 26 additions & 0 deletions doc/examples/vhpidirect/Caccess/cSharedVar.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <stdio.h>

int sizeInt;
int* getIntArrSize();

int* intArray;
int* getintArray_ptr();
void promptIndexValue();

char finishedChar;
char* getFinished_ptr();
void promptFinished();

static const char VHDL_BIT_STATE[] = { 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'};

enum VHDL_BIT_CHAR {
VHDL_U = 0,
VHDL_X = 1,
VHDL_0 = 2,
VHDL_1 = 3,
VHDL_Z = 4,
VHDL_W = 5,
VHDL_L = 6,
VHDL_H = 7,
VHDL_D = 8,
};
36 changes: 36 additions & 0 deletions doc/examples/vhpidirect/Caccess/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <malloc.h>

#include "cSharedVar.h"

extern int ghdl_main(char argc, char* argv[]);

int main(int argc, char const *argv[])
{
char strIn[3];
printf("Enter the Integer Array length [1-9]: ");
fgets(strIn, sizeof strIn, stdin);
printf("\n");
sscanf(strIn, "%d", &sizeInt);

if(sizeInt < 1)
sizeInt = 1;

intArray = malloc(sizeInt*sizeof(int));

for (int i = 0; i < sizeInt; i++)
{
intArray[i] = i*i;
}

printf("ghdl_main return: %d\n", ghdl_main(0, NULL));
printf("\n********************************\nghdl simulation completed.\n\n");

for (int i = 0; i < sizeInt; i++)
{
printf("intArray[%d] = %d\n", i, intArray[i]);
}

return 0;
}


33 changes: 33 additions & 0 deletions doc/examples/vhpidirect/Caccess/toplevel.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.cAccess.all;

entity toplevel is
end entity toplevel;

architecture RTL of toplevel is

begin

process
begin
report "array length: " & integer'image(c_intArr.all'length);

c_promptIndexValue(0);

for i in 1 to c_intArr.all'right loop
report "c_intArr[" & integer'image(i) &"] = " & integer'image(c_intArr.all(i)) & ". Set to: " & integer'image(2*c_intArr.all(i));
c_intArr.all(i) := 2*c_intArr.all(i);
end loop;

c_promptFinished;
if(c_finished.all = '1') then
wait;
end if;
report "c_finished = " & std_ulogic'image(c_finished.all);
end process;


end architecture RTL;
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
Data exchange through VHPIDIRECT
################################

.. toctree::
:hidden:

Caccess/README
demo/README

:ref:`VHPIDIRECT_Example:C_Access` is a straight forward example of executing the GHDL simulation from a personal entry point, while accessing variables (an int, int array and char).

See :ref:`Examples:VHPIDIRECT:Demo` for a demo about how to pass different types of data to/from VHDL and C through VHPIDIRECT.

VUnit
=====

Expand All @@ -16,3 +26,14 @@ ghdlex and netpp
`ghdlex <https://github.com/hackfin/ghdlex>`_ is a set of C extensions to facilitate data exchange between a GHDL simulation and external applications. VHPIDIRECT mechanisms are used to wrap GHDL data types into structures usable from a C library. `ghdlex` uses the `netpp <https://section5.ch/index.php/netpp/>`_ library to expose virtual entities (such as pins or RAM) to the network. It also demonstrates simple data I/O through unix pipes. A few VHDL example entities are provided, such as a virtual console, FIFOs, RAM.

The author of `netpp` and `ghdlex` is also working on `MaSoCist <https://github.com/hackfin/MaSoCist>`_, a linux'ish build system for System on Chip designs, based on GHDL. It allows to handle more complex setup, e.g. how a RISC-V architecture (for example) is regress-tested using a virtual debug interface.

SystemC and VHDL mixed simulation
=================================

There is an example under `Demo of mixed vhdl + systemc simulation <https://github.com/ghdl/ghdl-systemc-fosdem16>`_.


Examples Collection
===================

There is a collection of GHDL use cases under eine's `hwd-ide <https://github.com/eine/hwd-ide/tree/develop/examples>`_.
21 changes: 21 additions & 0 deletions doc/examples/vhpidirect/demo/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.. program:: ghdl
.. _Examples:VHPIDIRECT:Demo:

VHPIDIRECT Demo
===============

The following sources show how to pass different types of data to/from VHDL and C through VHPIDIRECT.

.. NOTE:: :file:`ghdl.h` is a reference of GHDL's ABI, which can be imported to easily convert data types. However, the ABI is not settled, so it might change without prior notice.

.. literalinclude:: run.sh
:language: bash

.. literalinclude:: tb.vhd
:language: vhdl

.. literalinclude:: main.c
:language: c

.. literalinclude:: ghdl.h
:language: c
Loading