Dynamic loading

Building either foreign resources or the VHDL simulation model as shared libraries allows to decouple the build procedures.

Loading foreign objects from within a simulation

Instead of linking and building foreign objects along with GHDL, it is also possible to load foreign resources dynamically. In order to do so, provide the path and name of the shared library where the resource is to be loaded from. For example:

attribute foreign of get_rand: function is "VHPIDIRECT ./getrand.so get_rand";

Loading a simulation

In order to generate a position independent executable (PIE), be it an executable binary or a shared library, GHDL must be built with config option --default-pic. This will ensure that all the libraries and sources analyzed by GHDL generate position independent code (PIC).

PIE binaries can be loaded and executed from any language that supports C-alike signatures and types (C, C++, golang, Python, Rust, etc.). For example, in Python:

import ctypes
gbin = ctypes.CDLL(bin_path)

args = ['-gGENA="value"', 'gGENB="value"']

xargs = (ctypes.POINTER(ctypes.c_char) * (len(args) + 1))()
for i, arg in enumerate(args):
    xargs[i] = ctypes.create_string_buffer(arg.encode('utf-8'))
return args[0], xargs

gbin.main(len(xargv)-1, xargv)

import _ctypes
# On GNU/Linux
_ctypes.dlclose(gbin._handle)
# On Windows
#_ctypes.FreeLibrary(gbin._handle)

This allows seamless co-simulation using concurrent/parallel execution features available in each language: pthreads, goroutines/gochannels, multiprocessing/queues, etc. Moreover, it provides a mechanism to execute multiple GHDL simulations in parallel.

Tip

As explained in Wrapping a simulation (ghdl_main), ghdl_main must be called once, since reseting/restarting the simulation runtime is not supported yet (see #1184). When it is loaded dynamically, this means that the binary file/library needs to be unloaded from memory and loaded again.

Attention

By default, GHDL uses grt.ver to limit which symbols are exposed in the generated binary, and ghdl_main is not included. Hence, the version script needs to be removed, or a complementary script needs to be provided. Otherwise, it will not be possible to find the function easily. See --list-link for further info.

Tip

See #803 for details about expected differences in the exit codes, depending on the version of the VHDL standard that is used.