[2/3] Add external modes to string_ptr and integer_vector_ptr (through VHPIDIRECT) by umarcor · Pull Request #476 · VUnit/vunit
Based on #482 and #507.
Refs #462, #465, #470.
@kraigher wrote:
So in this case the first task becomes to add a dynamic byte array data type to VUnit that can have an external implementation in a C-object. It is easier to review if such a task is done in isolation as a separate PR.
In this PR, external modes are added to integer_vector_ptr.vhd, following the same approach as in #507.
In order to support using *_ptr with or without VHPI, two different implementations of the external resources are provided. One of them, external_*_pkg-vhpi.vhd, declares the functions/procedures as external; therefore, C implementations must be provided. The other one, external_*_pkg-novhpi.vhd does not declare the functions/procedures as external; C implementations are not required, but it is not possible to create vectors with id/=0 (an assertion of level error is raised).
The list of objects is added through set_sim_option("ghdl.elab_flags", ["-Wl," + " ".join(files)]).
An example is added, external_buffer, to test accessing the same external buffer/array using two methods. The external C application allocates a buffer of length 15 and writes to the first 5 positions. In the VHDL testbench, two integer_vector_ptr are created. The first one is used to copy the first five elements to positions 5-9. And the second one is used to copy data from positions 5-9, to positions 10-14. The C application prints all the positions before and after the execution of the simulation.
deallocate, reallocate and resize are not implemented for external models. For the case id>0, it would be easy to implement it. Since the 'connection' is a pointer, it is possible to use malloc or mmap in the C implementation. Coherently, it would be possible to update the length in the VHDL model according to the actual size in the C app.
However, when extfnc, it can be complex or not possible. Since read_byte/write_byte can be used to interact with external services/processes through pipes, sockets, packets, messages, etc., the implementation is likely to be very specific. Nonetheless, in this example the implementation can be the same for both 'access' modes.