aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/using/Simulation.rst17
-rw-r--r--src/grt/grt-vpi.adb64
-rw-r--r--testsuite/vpi/vpi005/mydesign.vhdl9
-rwxr-xr-xtestsuite/vpi/vpi005/testsuite.sh35
-rw-r--r--testsuite/vpi/vpi005/vpi1.c13
-rw-r--r--testsuite/vpi/vpi005/vpi2.c13
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
+};