A simple interface

Let us take Yann's "bouton" (Push button) example. It can be found at the above listed web site in the GHDL/io_port folder of his GHDL extensions .tgz package. It polls the pins from a parallel port device under linux. We'll not elaborate on the hardware access functionality, just look at how GHDL calls C routines. For that, you'd define a function prototype in VHDL, but with some special attributes as follows:

<code>package boutons is procedure lecture_boutons (bouton1, bouton2, bouton3, bouton4: out std_ulogic); attribute foreign of lecture_boutons : procedure is "VHPIDIRECT lecture_boutons"; end boutons; </code>

We are not done yet, this is just the prototype. We'll also need some kind of function stub to actually wrap our code. In the same file, you'll find a package body:

<code>package body boutons is procedure lecture_boutons (bouton1, bouton2, bouton3, bouton4: out std_ulogic) is begin assert false report "VHPI" severity failure; end lecture_boutons; end boutons; </code>

That is the VHDL side. The C side is much shorter, here's the prototype for our button read function:

<code>void lecture_boutons(char boutons[4]);</code>

So you can see that the above buttons map into a char array. But what's contained in these chars? Remember, a std_logic_vector is not just an array of bits that are high or low. There can be a few more states like 'X', 'U', 'Z'. Therefore, a VHDL std_logic entity is one char wide. The encoding is listed in the ghpi.h file of our GHDL extensions.

Now, after we have written all the functionality, how do we bake our simulation?

It actually makes sense to collect all these C extensions in a library and link them, like you've possibly done that in GCC many times. So we'll first create a library with all the extensions:

ar ruv libmysim.a boutons.o my_other_extensions.o

Then, we'll translate the simulation VHDL a little different than in the above example. First, we analyze all the files, then we explicitely elaborate and link against the simulation with the ghdl -e command, but specifying link options:

<code>ghdl -a simbutton.vhdl boutons.vhdl # Analzye ghdl -e -Wl,-L. -Wl,-lmysim simbutton # Elaborate and link</code>

'simbutton' is the top level entity of your simulation again. You'd probably want to put these commands into a Makefile.

We have found so far, using Yanns examples, that we can call stuff from the GHDL simulation repeatedly, but we can not easily make a C program control the entire simulation in the sense of being a 'master'. But rethinking this wish, makes us probably realize that in real world we don't have this situation: If a front end is speaking to an FPGA device, it is happening mostly the asynchrononus way through some command interface, for example a USB FIFO. Why don't we just mimic this?