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#
By default, GHDL uses
grt.ver to limit which symbols are exposed in the generated artifacts, and
ghdl_main is not
included. See Generating shared libraries for guidelines to generate shared objects with
visible or filtered symbols.
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.). 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.
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 idx, arg in enumerate(args): xargs[idx+1] = ctypes.create_string_buffer(arg.encode('utf-8')) gbin.main(len(xargs)-1, xargs) import _ctypes # On GNU/Linux _ctypes.dlclose(gbin._handle) # On Windows #_ctypes.FreeLibrary(gbin._handle)
See a complete example written in C in shghdl.
As explained in Wrapping a simulation,
ghdl_main must be called once, since reseting/restarting
the simulation runtime is not supported yet (see ghdl#1184). When it is loaded dynamically, this means that the binary
file/library needs to be unloaded from memory and loaded again (as in shghdl).
See ghdl#803 for details about expected differences in the exit codes, depending on the version of the VHDL standard that is used.