aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Reynwar <ben@reynwar.net>2020-05-10 07:56:48 -0700
committerGitHub <noreply@github.com>2020-05-10 16:56:48 +0200
commita0919fe84b25f37d0307805650379830094fcfbf (patch)
tree01d1e5693e7ce954495eca1473319a32057c57fe
parent06202188e0e88c0096518415413c08bd0471644b (diff)
downloadghdl-a0919fe84b25f37d0307805650379830094fcfbf.tar.gz
ghdl-a0919fe84b25f37d0307805650379830094fcfbf.tar.bz2
ghdl-a0919fe84b25f37d0307805650379830094fcfbf.zip
Constants in vpi (#1297)
* Adding some very basic vpi tests. * Modify test so that's it's checking VPI access to constants. * Provide VPI to access constants. * Add vpi tests to testsuite. * Fix bug to allow getting values of generic/constant boolean and std_logic. * Fix stupid copying mistake in last commit. * Formatting and trying to get tests working on windows. * Fixing comment and removing redundant VhpiConstantDeclK
-rwxr-xr-xdist/ci-run.sh3
-rw-r--r--src/grt/grt-avhpi.adb31
-rw-r--r--src/grt/grt-vcd.adb3
-rw-r--r--src/grt/grt-vpi.adb25
-rw-r--r--src/grt/grt-vpi.ads1
-rwxr-xr-xtestsuite/testsuite.sh29
-rwxr-xr-xtestsuite/vpi/testsuite.sh53
-rw-r--r--testsuite/vpi/vpi001/mydesign.vhdl38
-rwxr-xr-xtestsuite/vpi/vpi001/testsuite.sh24
-rw-r--r--testsuite/vpi/vpi001/vpi1.c65
-rw-r--r--testsuite/vpi/vpi002/mydesign.vhdl46
-rwxr-xr-xtestsuite/vpi/vpi002/testsuite.sh28
-rw-r--r--testsuite/vpi/vpi002/vpi1.c80
-rw-r--r--testsuite/vpi/vpi003/mydesign.vhdl30
-rwxr-xr-xtestsuite/vpi/vpi003/testsuite.sh28
-rw-r--r--testsuite/vpi/vpi003/vpi1.c55
16 files changed, 524 insertions, 15 deletions
diff --git a/dist/ci-run.sh b/dist/ci-run.sh
index fa0d61f2e..131658cff 100755
--- a/dist/ci-run.sh
+++ b/dist/ci-run.sh
@@ -429,7 +429,7 @@ ci_run () {
if [ "x$IS_MACOS" = "xtrue" ]; then
CC=clang \
prefix="`cd ./install-mcode; pwd`/usr/local" \
- ./testsuite/testsuite.sh sanity gna vests
+ ./testsuite/testsuite.sh sanity gna vests vpi
else
# Build ghdl/ghdl:$GHDL_IMAGE_TAG image
build_img_ghdl
@@ -442,6 +442,7 @@ ci_run () {
if [ "x$ISSYNTH" = "xtrue" ]; then
tests="$tests synth"
fi
+ tests="$tests vpi"
$RUN "ghdl/ghdl:$GHDL_IMAGE_TAG" bash -c "GHDL=ghdl ./testsuite/testsuite.sh $tests"
fi
diff --git a/src/grt/grt-avhpi.adb b/src/grt/grt-avhpi.adb
index 374dcc3a6..5e234b9c7 100644
--- a/src/grt/grt-avhpi.adb
+++ b/src/grt/grt-avhpi.adb
@@ -126,7 +126,8 @@ package body Grt.Avhpi is
end case;
when VhpiIndexedNames =>
case Ref.Kind is
- when VhpiGenericDeclK =>
+ when VhpiGenericDeclK |
+ VhpiConstDeclK=>
Res := (Kind => AvhpiNameIteratorK,
Ctxt => Ref.Ctxt,
N_Addr => Avhpi_Get_Address (Ref),
@@ -184,7 +185,8 @@ package body Grt.Avhpi is
El_Type1 : Ghdl_Rti_Access;
begin
case Obj_Rti.Common.Kind is
- when Ghdl_Rtik_Generic =>
+ when Ghdl_Rtik_Generic |
+ Ghdl_Rtik_Constant =>
Is_Sig := False;
when others =>
Internal_Error ("add_index");
@@ -391,6 +393,10 @@ package body Grt.Avhpi is
Res := (Kind => VhpiGenericDeclK,
Ctxt => Ctxt,
Obj => To_Ghdl_Rtin_Object_Acc (Rti));
+ when Ghdl_Rtik_Constant =>
+ Res := (Kind => VhpiConstDeclK,
+ Ctxt => Ctxt,
+ Obj => To_Ghdl_Rtin_Object_Acc (Rti));
when Ghdl_Rtik_Subtype_Array =>
declare
Atype : constant Ghdl_Rtin_Subtype_Composite_Acc :=
@@ -480,6 +486,7 @@ package body Grt.Avhpi is
case Ch.Kind is
when Ghdl_Rtik_Port
| Ghdl_Rtik_Generic
+ | Ghdl_Rtik_Constant
| Ghdl_Rtik_Signal
| Ghdl_Rtik_Type_Array
| Ghdl_Rtik_Subtype_Array
@@ -599,7 +606,8 @@ package body Grt.Avhpi is
return Obj.Inst.Name;
when VhpiSigDeclK
| VhpiPortDeclK
- | VhpiGenericDeclK =>
+ | VhpiGenericDeclK
+ | VhpiConstDeclK =>
return Obj.Obj.Name;
when VhpiSubtypeDeclK =>
return To_Ghdl_Rtin_Subtype_Scalar_Acc (Obj.Atype).Name;
@@ -715,7 +723,8 @@ package body Grt.Avhpi is
Add (Obj.Inst.Name);
when VhpiSigDeclK
| VhpiPortDeclK
- | VhpiGenericDeclK =>
+ | VhpiGenericDeclK
+ | VhpiConstDeclK =>
Add (Obj.Obj.Name);
when VhpiIfGenerateK =>
Add (To_Ghdl_Rtin_Generate_Acc
@@ -937,7 +946,8 @@ package body Grt.Avhpi is
| VhpiSubtypeDeclK
| VhpiArrayTypeDeclK =>
Atype := Ref.Atype;
- when VhpiGenericDeclK =>
+ when VhpiGenericDeclK
+ | VhpiConstDeclK =>
Atype := Ref.Obj.Obj_Type;
when VhpiIndexedNameK =>
Atype := Ref.N_Type;
@@ -1130,7 +1140,8 @@ package body Grt.Avhpi is
case Obj.Kind is
when VhpiSigDeclK
| VhpiPortDeclK
- | VhpiGenericDeclK =>
+ | VhpiGenericDeclK
+ | VhpiConstDeclK =>
-- Objects.
Linecol := Obj.Obj.Linecol;
when VhpiPackInstK
@@ -1230,7 +1241,8 @@ package body Grt.Avhpi is
return Obj.Atype;
when VhpiSigDeclK
| VhpiPortDeclK
- | VhpiGenericDeclK =>
+ | VhpiGenericDeclK
+ | VhpiConstDeclK =>
return To_Ghdl_Rti_Access (Obj.Obj);
when others =>
return null;
@@ -1288,8 +1300,13 @@ package body Grt.Avhpi is
Vptr := To_Ghdl_Value_Ptr (Obj.N_Addr);
Atype := Obj.N_Type;
when VhpiGenericDeclK =>
+ -- Putting values for generics is necessary to support SDF
+ -- annotations.
Vptr := To_Ghdl_Value_Ptr (Avhpi_Get_Address (Obj));
Atype := Obj.Obj.Obj_Type;
+ when VhpiConstDeclK =>
+ -- Don't support changing values of constants.
+ return AvhpiErrorNotImplemented;
when others =>
return AvhpiErrorNotImplemented;
end case;
diff --git a/src/grt/grt-vcd.adb b/src/grt/grt-vcd.adb
index 6722f2a75..aab295555 100644
--- a/src/grt/grt-vcd.adb
+++ b/src/grt/grt-vcd.adb
@@ -416,7 +416,8 @@ package body Grt.Vcd is
end case;
when VhpiSigDeclK =>
Val := Vcd_Effective;
- when VhpiGenericDeclK =>
+ when VhpiGenericDeclK
+ | VhpiConstDeclK =>
Val := Vcd_Variable;
when others =>
Info := (Vtype => Vcd_Bad,
diff --git a/src/grt/grt-vpi.adb b/src/grt/grt-vpi.adb
index a2884bd76..afcc2692f 100644
--- a/src/grt/grt-vpi.adb
+++ b/src/grt/grt-vpi.adb
@@ -574,6 +574,15 @@ package body Grt.Vpi is
return vpiParameter;
end if;
end;
+ when VhpiConstDeclK =>
+ declare
+ Info : Verilog_Wire_Info;
+ begin
+ Get_Verilog_Wire (Res, Info);
+ if Info.Vtype /= Vcd_Bad then
+ return vpiConstant;
+ end if;
+ end;
when others =>
null;
end case;
@@ -596,6 +605,9 @@ package body Grt.Vpi is
when vpiParameter =>
return new struct_vpiHandle'(mType => vpiParameter,
Ref => Res);
+ when vpiConstant =>
+ return new struct_vpiHandle'(mType => vpiConstant,
+ Ref => Res);
when others =>
return null;
end case;
@@ -859,7 +871,8 @@ package body Grt.Vpi is
case Vhpi_Get_Kind (Obj) is
when VhpiPortDeclK
| VhpiSigDeclK
- | VhpiGenericDeclK =>
+ | VhpiGenericDeclK
+ | VhpiConstDeclK =>
null;
when others =>
return null;
@@ -894,13 +907,15 @@ package body Grt.Vpi is
Append_Bin (Ghdl_U64 (V), 32);
end;
when Vcd_Bit
- | Vcd_Bool
- | Vcd_Bitvector =>
+ | Vcd_Bool =>
+ Append (Buf_Value, Map_Std_B1 (Verilog_Wire_Val (Info).B1));
+ when Vcd_Bitvector =>
for J in 0 .. Len - 1 loop
Append (Buf_Value, Map_Std_B1 (Verilog_Wire_Val (Info, J).B1));
end loop;
- when Vcd_Stdlogic
- | Vcd_Stdlogic_Vector =>
+ when Vcd_Stdlogic =>
+ Append (Buf_Value, E8_To_Char (Verilog_Wire_Val (Info).E8));
+ when Vcd_Stdlogic_Vector =>
for J in 0 .. Len - 1 loop
Append (Buf_Value, E8_To_Char (Verilog_Wire_Val (Info, J).E8));
end loop;
diff --git a/src/grt/grt-vpi.ads b/src/grt/grt-vpi.ads
index 578ed23af..353451edd 100644
--- a/src/grt/grt-vpi.ads
+++ b/src/grt/grt-vpi.ads
@@ -38,6 +38,7 @@ package Grt.Vpi is
vpiSize : constant Integer := 4;
vpiFile : constant Integer := 5;
vpiLineNo : constant Integer := 6;
+ vpiConstant : constant Integer := 7;
vpiDefName : constant Integer := 9;
vpiTimePrecision : constant Integer := 12;
diff --git a/testsuite/testsuite.sh b/testsuite/testsuite.sh
index ae6b7f54f..f060e763c 100755
--- a/testsuite/testsuite.sh
+++ b/testsuite/testsuite.sh
@@ -177,6 +177,32 @@ do_synth () {
#---
+do_vpi () {
+ gstart "[GHDL - test] vpi"
+ cd vpi
+
+ for d in *[0-9]; do
+ cd $d
+ if ./testsuite.sh > test.log 2>&1 ; then
+ printf "vpi $d: ${ANSI_GREEN}ok${ANSI_NOCOLOR}\n"
+ # Don't disp log
+ else
+ printf "vpi $d: ${ANSI_RED}failed${ANSI_NOCOLOR}\n"
+ cat test.log
+ failures="$failures $d"
+ fi
+ cd ..
+ # Stop at the first failure
+ [ "$failures" = "" ] || break
+ done
+
+ cd ..
+ gend
+ [ "$failures" = "" ] || exit 1
+}
+
+#---
+
if [ "x$GHDL" = "x" ]; then
if [ "x$prefix" != "x" ]; then
export GHDL="$prefix/bin/ghdl"
@@ -200,7 +226,7 @@ for opt; do
esac
done
-if [ "x$tests" = "x" ]; then tests="sanity gna vests synth"; fi
+if [ "x$tests" = "x" ]; then tests="sanity gna vests synth vpi"; fi
echo "tests: $tests"
@@ -211,6 +237,7 @@ do_test() {
gna) do_gna;;
vests) do_vests;;
synth) do_synth;;
+ vpi) do_vpi;;
*)
printf "${ANSI_RED}$0: test name '$1' is unknown${ANSI_NOCOLOR}\n"
exit 1;;
diff --git a/testsuite/vpi/testsuite.sh b/testsuite/vpi/testsuite.sh
new file mode 100755
index 000000000..12b367f2c
--- /dev/null
+++ b/testsuite/vpi/testsuite.sh
@@ -0,0 +1,53 @@
+#! /bin/sh
+
+# Driver for a testsuite.
+
+set -e
+
+# This is the only place where test dirs are specified. Do not duplicate this
+# line
+dirs="*[0-9]"
+
+failures=""
+full=n
+
+for opt; do
+ case "$opt" in
+ -k | --keep-going) full=y ;;
+ --dir=*) dirs=`echo $opt | sed -e 's/--dir=//'` ;;
+ --skip=*) d=`echo $opt | sed -e 's/--skip=//'`
+ dirs=`echo "" $dirs | sed -e "s/ $d//"` ;;
+ --start-at=*) d=`echo $opt | sed -e 's/--start-at=//'`
+ dirs=`echo "" $dirs | sed -e "s/^.* $d//"`
+ dirs="$d $dirs" ;;
+ --list-tests) echo $dirs; exit 0;;
+ *) echo "Unknown option $opt"
+ exit 2
+ ;;
+ esac
+done
+
+singlerun() {
+ echo ""
+ echo "dir $1:"
+ cd $1
+ if ! ./testsuite.sh; then
+ echo "#################################################################"
+ echo "######### FAILURE: $1"
+ echo "#################################################################"
+ if [ $2 = "y" ]; then
+ failures="$failures $1"
+ else
+ exit 1;
+ fi
+ fi
+ cd ..
+}
+
+for i in $dirs; do singlerun $i $full; done
+
+if [ x"$failures" = x"" ]; then
+ echo "tests are successful" && exit 0
+else
+ echo "test failed ($failures)" && exit 1
+fi
diff --git a/testsuite/vpi/vpi001/mydesign.vhdl b/testsuite/vpi/vpi001/mydesign.vhdl
new file mode 100644
index 000000000..6b420ac7a
--- /dev/null
+++ b/testsuite/vpi/vpi001/mydesign.vhdl
@@ -0,0 +1,38 @@
+library ieee ;
+use ieee.std_logic_1164.all;
+
+entity myentity is
+ generic (
+ genint: integer := 42;
+ genstring: string := "fish";
+ genbool: boolean := True;
+ gensl: std_logic := '0'
+ );
+ port (
+ iportbool: in boolean;
+ iportint: in integer;
+ iportsl: in std_logic;
+ oportbool: out boolean;
+ oportint: out integer;
+ oportsl: out std_logic
+ );
+end myentity;
+
+architecture arch of myentity is
+ constant constsl: std_logic := '0';
+ signal sigsl: std_logic;
+ constant constint: integer := 42;
+ signal sigint: integer;
+ constant constbool: boolean := True;
+ signal sigbool: boolean;
+ constant conststring: string := "fish";
+begin
+ sigsl <= iportsl;
+ sigbool <= iportbool;
+ sigint <= iportint;
+
+ oportbool <= constbool;
+ oportint <= constint;
+ oportsl <= constsl;
+
+end arch;
diff --git a/testsuite/vpi/vpi001/testsuite.sh b/testsuite/vpi/vpi001/testsuite.sh
new file mode 100755
index 000000000..a3edac791
--- /dev/null
+++ b/testsuite/vpi/vpi001/testsuite.sh
@@ -0,0 +1,24 @@
+#! /bin/sh
+
+. ../../testenv.sh
+
+analyze mydesign.vhdl
+elab myentity
+
+if ghdl_has_feature myentity vpi; then
+ $GHDL --vpi-compile -v gcc -c vpi1.c
+ $GHDL --vpi-link -v gcc -o vpi1.vpi vpi1.o
+
+ add_vpi_path
+
+ simulate myentity --vpi=./vpi1.vpi | tee myentity.out
+ if grep -q Error myentity.out; then
+ echo "Error in output"
+ exit 1;
+ fi
+
+ rm -f vpi1.vpi vpi1.o myentity.out
+fi
+clean
+
+echo "Test successful"
diff --git a/testsuite/vpi/vpi001/vpi1.c b/testsuite/vpi/vpi001/vpi1.c
new file mode 100644
index 000000000..c4943fde6
--- /dev/null
+++ b/testsuite/vpi/vpi001/vpi1.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <vpi_user.h>
+#define N_NAMES 12
+
+void
+vpi_proc (void)
+{
+ vpiHandle net;
+ s_vpi_value val;
+ char names[N_NAMES][64] =
+ {
+ // Integers
+ "myentity.sigint",
+ "myentity.iportint",
+ "myentity.genint",
+ "myentity.constint",
+
+ // Std_logic
+ "myentity.sigsl",
+ "myentity.iportsl",
+ "myentity.gensl",
+ "myentity.constsl",
+
+ // Boolean
+ "myentity.sigbool",
+ "myentity.iportbool",
+ "myentity.genbool",
+ "myentity.constbool",
+
+ // String
+ //"myentity.genstring", -- Not supported
+ //"myentity.conststring" -- Not supported
+ };
+
+ for (int name_index=0; name_index<N_NAMES; name_index+=1) {
+ printf ("Trying to find name %s\n", names[name_index]);
+ net = vpi_handle_by_name (names[name_index], NULL);
+ if (net == NULL)
+ {
+ printf ("Error: Failed to find the net %s\n", names[name_index]);
+ return;
+ }
+ val.format = vpiBinStrVal;
+ vpi_get_value (net, &val);
+ printf ("value: %s\n", val.value.str);
+ }
+}
+
+void my_handle_register()
+{
+ s_cb_data cb;
+ printf ("Hello world\n");
+
+ cb.reason = cbEndOfCompile;
+ cb.cb_rtn = &vpi_proc;
+ cb.user_data = NULL;
+ if (vpi_register_cb (&cb) == NULL)
+ vpi_printf ("Error: Cannot register EndOfCompile call back\n");
+}
+
+void (*vlog_startup_routines[]) () =
+{
+ my_handle_register,
+ 0
+};
diff --git a/testsuite/vpi/vpi002/mydesign.vhdl b/testsuite/vpi/vpi002/mydesign.vhdl
new file mode 100644
index 000000000..c542f5fa9
--- /dev/null
+++ b/testsuite/vpi/vpi002/mydesign.vhdl
@@ -0,0 +1,46 @@
+library ieee ;
+use ieee.std_logic_1164.all;
+
+package mypackage is
+ type myenum is (ONE, TWO, THREE);
+ subtype myarray is bit_vector(2 downto 0);
+ type myarray5 is array(1 downto 0) of bit;
+end package;
+
+library ieee ;
+use ieee.std_logic_1164.all;
+use work.mypackage.all;
+
+entity myentity is
+ generic (
+ width: integer := 2;
+ genenum: myenum := ONE;
+ genarray1: bit_vector(1 downto 0) := "01";
+ genarray3: myarray := "010";
+ genarray5: myarray5 := ('1', '0')
+ );
+ port (
+ portenum: in myenum;
+ portarray1: in bit_vector(1 downto 0);
+ portarray2: in bit_vector(width downto 0);
+ portarray3: in myarray;
+ portarray5: in myarray5
+ );
+end myentity;
+
+architecture arch of myentity is
+ subtype myarray4 is bit_vector(width downto 0);
+ signal sigenum: myenum;
+ constant constenum: myenum := ONE;
+ signal sigarray1: bit_vector(1 downto 0);
+ constant constarray1: bit_vector(1 downto 0) := "10";
+ signal sigarray2: bit_vector(width downto 0);
+ constant constarray2: bit_vector(width downto 0) := (others => '1');
+ signal sigarray3: myarray;
+ constant constarray3: myarray := "101";
+ signal sigarray4: myarray4;
+ constant constarray4: myarray4:= (others => '1');
+ signal sigarray5: myarray5;
+ constant constarray5: myarray5:= (others => '1');
+begin
+end arch;
diff --git a/testsuite/vpi/vpi002/testsuite.sh b/testsuite/vpi/vpi002/testsuite.sh
new file mode 100755
index 000000000..508ad6b65
--- /dev/null
+++ b/testsuite/vpi/vpi002/testsuite.sh
@@ -0,0 +1,28 @@
+#! /bin/sh
+
+. ../../testenv.sh
+
+analyze mydesign.vhdl
+elab myentity
+
+if ghdl_has_feature myentity vpi; then
+ $GHDL --vpi-compile -v gcc -c vpi1.c
+ $GHDL --vpi-link -v gcc -o vpi1.vpi vpi1.o
+
+ add_vpi_path
+
+ simulate myentity --vpi=./vpi1.vpi | tee myentity.out
+ if grep -q Error myentity.out; then
+ echo "Error in output"
+ exit 1;
+ fi
+ if grep -q error myentity.out; then
+ echo "error in output"
+ exit 1;
+ fi
+
+ rm -f vpi1.vpi vpi1.o
+fi
+clean
+
+echo "Test successful"
diff --git a/testsuite/vpi/vpi002/vpi1.c b/testsuite/vpi/vpi002/vpi1.c
new file mode 100644
index 000000000..f992e8246
--- /dev/null
+++ b/testsuite/vpi/vpi002/vpi1.c
@@ -0,0 +1,80 @@
+#include <stdio.h>
+#include <vpi_user.h>
+#define N_NAMES 12
+
+void
+vpi_proc (void)
+{
+ vpiHandle net;
+ s_vpi_value val;
+ char names[N_NAMES][64] =
+ {
+ // Enum
+ "myentity.sigenum",
+ "myentity.portenum",
+ "myentity.genenum",
+ //"myentity.constenum" // Not supported
+
+ // Array1 (unbounded static)
+ "myentity.sigarray1",
+ "myentity.portarray1",
+ //"myentity.genarray1", // Not supported
+ //"myentity.constarray1" // Not supported
+ //"myentity.sigarray1[0]", // Not supported
+ //"myentity.portarray1[0]", // Not supported
+
+ // Array2 (unbounded complex)
+ "myentity.sigarray2",
+ "myentity.portarray2",
+ //"myentity.constarray2" // Not supported
+
+ // Array3 (bounded static)
+ "myentity.sigarray3",
+ "myentity.portarray3",
+ //"myentity.genarray3", // Not supported
+ //"myentity.constarray3" // Not supported
+
+ // Array4 (bounded complex)
+ "myentity.sigarray4",
+ //"myentity.constarray4" // Not supported
+
+ // Array4 (bounded static) array of bit
+ "myentity.sigarray5",
+ "myentity.portarray5",
+ //"myentity.constarray5", // Not supported
+ //"myentity.genarray5", // Not supported
+ //"myentity.sigarray5[0]", // Not supported
+ //"myentity.portarray5[0]" // Not supported
+ };
+
+ for (int name_index=0; name_index<N_NAMES; name_index+=1) {
+ printf ("Trying to find name %s\n", names[name_index]);
+ net = vpi_handle_by_name (names[name_index], NULL);
+ if (net == NULL)
+ {
+ printf ("Error: Failed to find the net %s\n", names[name_index]);
+ return;
+ }
+ val.format = vpiBinStrVal;
+ vpi_get_value (net, &val);
+ printf ("value: %s\n", val.value.str);
+ }
+}
+
+void my_handle_register()
+{
+ s_cb_data cb;
+ printf ("Hello world\n");
+
+ cb.reason = cbEndOfCompile;
+ cb.cb_rtn = &vpi_proc;
+ cb.user_data = NULL;
+ if (vpi_register_cb (&cb) == NULL)
+ vpi_printf ("Error: Cannot register EndOfCompile call back\n");
+}
+
+void (*vlog_startup_routines[]) () =
+{
+ my_handle_register,
+ 0
+};
diff --git a/testsuite/vpi/vpi003/mydesign.vhdl b/testsuite/vpi/vpi003/mydesign.vhdl
new file mode 100644
index 000000000..89fe47783
--- /dev/null
+++ b/testsuite/vpi/vpi003/mydesign.vhdl
@@ -0,0 +1,30 @@
+library ieee ;
+use ieee.std_logic_1164.all;
+
+package mypackage is
+ type myarray2dim is array(1 downto 0, 1 downto 0) of bit;
+ type myarray1 is array(1 downto 0) of bit_vector(1 downto 0);
+end package;
+
+library ieee ;
+use ieee.std_logic_1164.all;
+use work.mypackage.all;
+
+entity myentity is
+ generic (
+ genarr2dim: in myarray2dim := (('0', '0'), ('1', '1'));
+ genarray1: in myarray1 := ("10", "10")
+ );
+ port (
+ portarr2dim: in myarray2dim;
+ portarray1: in myarray1
+ );
+end myentity;
+
+architecture arch of myentity is
+ signal sigarray2dim: myarray2dim;
+ signal constarray2dim: myarray2dim := (('0', '0'), ('1', '1'));
+ signal sigarray1: myarray1;
+ signal constarray1: myarray1 := ("10", "10");
+begin
+end arch;
diff --git a/testsuite/vpi/vpi003/testsuite.sh b/testsuite/vpi/vpi003/testsuite.sh
new file mode 100755
index 000000000..508ad6b65
--- /dev/null
+++ b/testsuite/vpi/vpi003/testsuite.sh
@@ -0,0 +1,28 @@
+#! /bin/sh
+
+. ../../testenv.sh
+
+analyze mydesign.vhdl
+elab myentity
+
+if ghdl_has_feature myentity vpi; then
+ $GHDL --vpi-compile -v gcc -c vpi1.c
+ $GHDL --vpi-link -v gcc -o vpi1.vpi vpi1.o
+
+ add_vpi_path
+
+ simulate myentity --vpi=./vpi1.vpi | tee myentity.out
+ if grep -q Error myentity.out; then
+ echo "Error in output"
+ exit 1;
+ fi
+ if grep -q error myentity.out; then
+ echo "error in output"
+ exit 1;
+ fi
+
+ rm -f vpi1.vpi vpi1.o
+fi
+clean
+
+echo "Test successful"
diff --git a/testsuite/vpi/vpi003/vpi1.c b/testsuite/vpi/vpi003/vpi1.c
new file mode 100644
index 000000000..e8e538ef6
--- /dev/null
+++ b/testsuite/vpi/vpi003/vpi1.c
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <vpi_user.h>
+#define N_NAMES 0
+
+void
+vpi_proc (void)
+{
+ vpiHandle net;
+ s_vpi_value val;
+ char names[N_NAMES][64] =
+ {
+ // Array 2 dimensional (Not supported)
+ //"myentity.sigarray2dim",
+ //"myentity.portarray2dim",
+ //"myentity.genarray2dim",
+ //"myentity.constarray2dim"
+
+ // Array of bit_vectors (Not supported)
+ //"myentity.sigarray1",
+ //"myentity.portarray1",
+ //"myentity.genarray1",
+ //"myentity.constarray1"
+ };
+
+ for (int name_index=0; name_index<N_NAMES; name_index+=1) {
+ printf ("Trying to find name %s\n", names[name_index]);
+ net = vpi_handle_by_name (names[name_index], NULL);
+ if (net == NULL)
+ {
+ printf ("Error: Failed to find the net %s\n", names[name_index]);
+ return;
+ }
+ val.format = vpiBinStrVal;
+ vpi_get_value (net, &val);
+ printf ("value: %s\n", val.value.str);
+ }
+}
+
+void my_handle_register()
+{
+ s_cb_data cb;
+ printf ("Hello world\n");
+
+ cb.reason = cbEndOfCompile;
+ cb.cb_rtn = &vpi_proc;
+ cb.user_data = NULL;
+ if (vpi_register_cb (&cb) == NULL)
+ vpi_printf ("Error: Cannot register EndOfCompile call back\n");
+}
+
+void (*vlog_startup_routines[]) () =
+{
+ my_handle_register,
+ 0
+};