diff options
author | Marlon James <marlon.james@gmail.com> | 2021-03-01 12:44:02 -0800 |
---|---|---|
committer | tgingold <tgingold@users.noreply.github.com> | 2021-03-02 07:50:54 +0100 |
commit | a03aedddf650f923b06ebacb441a713930cd63e1 (patch) | |
tree | 13056350de2379e39802cda292c7bc023779c67f | |
parent | f5e3ef10265440a3efc95281fef295cba6aab8a9 (diff) | |
download | ghdl-a03aedddf650f923b06ebacb441a713930cd63e1.tar.gz ghdl-a03aedddf650f923b06ebacb441a713930cd63e1.tar.bz2 ghdl-a03aedddf650f923b06ebacb441a713930cd63e1.zip |
VPI: support loading multiple libraries
-rw-r--r-- | doc/using/Simulation.rst | 17 | ||||
-rw-r--r-- | src/grt/grt-vpi.adb | 64 | ||||
-rw-r--r-- | testsuite/vpi/vpi005/mydesign.vhdl | 9 | ||||
-rwxr-xr-x | testsuite/vpi/vpi005/testsuite.sh | 35 | ||||
-rw-r--r-- | testsuite/vpi/vpi005/vpi1.c | 13 | ||||
-rw-r--r-- | testsuite/vpi/vpi005/vpi2.c | 13 |
6 files changed, 132 insertions, 19 deletions
diff --git a/doc/using/Simulation.rst b/doc/using/Simulation.rst index 607227042..807a634e2 100644 --- a/doc/using/Simulation.rst +++ b/doc/using/Simulation.rst @@ -146,15 +146,20 @@ Here is the list of the most useful options. For further info, see :ref:`DEV:Deb .. option:: --vpi=<FILENAME> - Load VPI module. + Load VPI library. This option can be used multiple times to load different libraries. - .. HINT:: - Currently, although multiple ``--vpi=`` options can be passed, only the last one is kept/used. However, handling - more than one shouldn't be a difficult change. + Any registration functions in the ``vlog_startup_routines`` array in the library will be called: + + .. code-block:: c + + void (*vlog_startup_routines[]) () = { + my_handle_register, + 0 + }; -.. option:: --vpi-trace=<FILE> +.. option:: --vpi-trace[=<FILENAME>] - Trace vpi calls to FILE. + Trace vpi calls. Trace is printed to :file:`FILENAME` if provided, otherwise to stdout. .. option:: --help diff --git a/src/grt/grt-vpi.adb b/src/grt/grt-vpi.adb index e32593734..34301086c 100644 --- a/src/grt/grt-vpi.adb +++ b/src/grt/grt-vpi.adb @@ -1842,8 +1842,16 @@ package body Grt.Vpi is -- * * * G H D L h o o k s * * * * * * * * * * * * * * * * * * * * * * * ------------------------------------------------------------------------------ - -- VCD filename. - Vpi_Filename : String_Access := null; + + type Lib_Cell; + type Lib_Access is access Lib_Cell; + + type Lib_Cell is record + File_Name : String_Access; + Next : Lib_Access; + end record; + + Vpi_Libraries : Lib_Access := null; ------------------------------------------------------------------------ -- Return TRUE if OPT is an option for VPI. @@ -1855,10 +1863,32 @@ package body Grt.Vpi is return False; end if; if Opt'Length > 6 and then Opt (F + 5) = '=' then - -- Add an extra NUL character. - Vpi_Filename := new String (1 .. Opt'Length - 6 + 1); - Vpi_Filename (1 .. Opt'Length - 6) := Opt (F + 6 .. Opt'Last); - Vpi_Filename (Vpi_Filename'Last) := NUL; + declare + Lib : Lib_Access; + File : String_Access; + begin + -- Store library info. + Lib := new Lib_Cell; + -- Add an extra NUL character. + File := new String (1 .. Opt'Length - 6 + 1); + File (1 .. Opt'Length - 6) := Opt (F + 6 .. Opt'Last); + File (File'Last) := NUL; + Lib.File_Name := File; + + -- Add new library to the list. + if Vpi_Libraries = null then + Vpi_Libraries := Lib; + else + declare + L : Lib_Access := Vpi_Libraries; + begin + while L.Next /= null loop + L := L.Next; + end loop; + L.Next := Lib; + end; + end if; + end; return True; elsif Opt'Length >= 11 and then Opt (F + 5 .. F + 10) = "-trace" then if Opt'Length > 11 and then Opt (F + 11) = '=' then @@ -1894,8 +1924,9 @@ package body Grt.Vpi is ------------------------------------------------------------------------ procedure Vpi_Help is begin - Put_Line (" --vpi=FILENAME load VPI module"); - Put_Line (" --vpi-trace[=FILE] trace vpi calls to FILE"); + Put_Line (" --vpi=FILENAME load VPI library"); + Put_Line + (" --vpi-trace[=FILE] trace vpi calls to stdout or provided FILE"); end Vpi_Help; ------------------------------------------------------------------------ @@ -1907,12 +1938,19 @@ package body Grt.Vpi is procedure Vpi_Init is + Lib : Lib_Access := Vpi_Libraries; begin - if Vpi_Filename /= null then - if LoadVpiModule (Vpi_Filename.all'Address) /= 0 then - Error ("cannot load VPI module"); - end if; + if Lib = null then + return; end if; + while Lib /= null loop + if LoadVpiModule (Lib.File_Name.all'Address) /= 0 then + Error_S ("cannot load VPI module '"); + Diag_C (Lib.File_Name.all); + Error_E ("'"); + end if; + Lib := Lib.Next; + end loop; end Vpi_Init; ------------------------------------------------------------------------ @@ -1922,7 +1960,7 @@ package body Grt.Vpi is Res : Integer; pragma Unreferenced (Res); begin - if Vpi_Filename = null then + if Vpi_Libraries = null then return; end if; diff --git a/testsuite/vpi/vpi005/mydesign.vhdl b/testsuite/vpi/vpi005/mydesign.vhdl new file mode 100644 index 000000000..38fdfda98 --- /dev/null +++ b/testsuite/vpi/vpi005/mydesign.vhdl @@ -0,0 +1,9 @@ +library ieee ; +use ieee.std_logic_1164.all; + +entity myentity is +end myentity; + +architecture arch of myentity is +begin +end arch; diff --git a/testsuite/vpi/vpi005/testsuite.sh b/testsuite/vpi/vpi005/testsuite.sh new file mode 100755 index 000000000..b692167c9 --- /dev/null +++ b/testsuite/vpi/vpi005/testsuite.sh @@ -0,0 +1,35 @@ +#! /bin/sh + +. ../../testenv.sh + +analyze mydesign.vhdl +elab myentity + +if c_compiler_is_available && ghdl_has_feature myentity vpi; then + $GHDL --vpi-compile -v gcc -c vpi1.c + $GHDL --vpi-link -v gcc -o vpi1.vpi vpi1.o + + $GHDL --vpi-compile -v gcc -c vpi2.c + $GHDL --vpi-link -v gcc -o vpi2.vpi vpi2.o + + add_vpi_path + + simulate myentity --vpi=./vpi1.vpi --vpi=./vpi2.vpi | tee myentity.out + if grep -q error myentity.out; then + echo "error in output" + exit 1; + fi + if ! grep -q "VPI lib 1" myentity.out; then + echo "VPI Library 1 not loaded" + exit 1; + fi + if ! grep -q "VPI lib 2" myentity.out; then + echo "VPI Library 2 not loaded" + exit 1; + fi + + rm -f vpi1.vpi vpi1.o vpi2.vpi vpi2.o myentity.out +fi +clean + +echo "Test successful" diff --git a/testsuite/vpi/vpi005/vpi1.c b/testsuite/vpi/vpi005/vpi1.c new file mode 100644 index 000000000..f2cccd286 --- /dev/null +++ b/testsuite/vpi/vpi005/vpi1.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <vpi_user.h> + +void my_startup() +{ + printf ("VPI lib 1\n"); +} + +void (*vlog_startup_routines[]) () = +{ + my_startup, + 0 +}; diff --git a/testsuite/vpi/vpi005/vpi2.c b/testsuite/vpi/vpi005/vpi2.c new file mode 100644 index 000000000..e41469b82 --- /dev/null +++ b/testsuite/vpi/vpi005/vpi2.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <vpi_user.h> + +void my_startup() +{ + printf ("VPI lib 2\n"); +} + +void (*vlog_startup_routines[]) () = +{ + my_startup, + 0 +}; |