GHDL coupling to C via VHPI
Motivation
It is often useful to call into c-libraries from within a VHDL simulation/testbench
- because VHDL standard library is too limited (e.g. file-io has no select())
- to access inter process communication features of Linux (e.g. pseudo terminals to interact with eb-tools)
- to access verilog components that are running as Verilator generated (i.e. verilated) C++ libraries
This HOW-TO describes how to declare a function or procedure in VHDL and implement it in C. Some information can be found
here and
here. The purpose of this page is to summarize the most relevant pieces of information.
Declare a function in VHDL without implementing it
- Declare the function like normal in the package header
- Set the "foreign" attribute of that function to "VHPIDIRECT <name_of_the_function>"
- Write a dummy implementation of that function with an "assert false" statement to make sure the dummy implementation is never called (or the simulation stops whenever it is called)
File vhpi_example.vhdl
package vhpi_example is
function integer_fun(i_arg : integer) return integer;
attribute foreign of integer_fun : function is "VHPIDIRECT integer_fun";
end package;
package body vhpi_example is
function integer_fun(i_arg : integer) return integer is
begin
assert false report "VHPI" severity failure;
return 0;
end function;
end package body;
Write a C implementation of the function
File vhpi_example_c.c
#include <stdio.h>
int integer_fun(int i_arg) {
int result = 1234;
printf("C-side integer_fun: i_arg = %d, returning %d\n", i_arg, result);
return result;
}
Compile the C-file
gcc -c vhpi_example_c.c
. In the vhdl testbench, use the package with the function like normal. When linking the testbench, pass the object file with the C-implementation like so:
ghdl -m -Wl,vhpi_example_c.o $(GHDLFLAGS) testbench
Data types other than integer
The simplest option is to use integers in the VHPI interfaces, because they are "integer" on the VHDL side and "int" on the C-side. For other common data-types (e.g. std_logic or std_logic_vector) this is not the case. In the attachment is an example that shows how to use data types such as strings, std_logic, std_logic_vector and a simple record.
--
MichaelReese - 24 Jun 2020