From a0919fe84b25f37d0307805650379830094fcfbf Mon Sep 17 00:00:00 2001 From: Ben Reynwar Date: Sun, 10 May 2020 07:56:48 -0700 Subject: 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 --- dist/ci-run.sh | 3 +- src/grt/grt-avhpi.adb | 31 +++++++++++---- src/grt/grt-vcd.adb | 3 +- src/grt/grt-vpi.adb | 25 +++++++++--- src/grt/grt-vpi.ads | 1 + testsuite/testsuite.sh | 29 +++++++++++++- testsuite/vpi/testsuite.sh | 53 +++++++++++++++++++++++++ testsuite/vpi/vpi001/mydesign.vhdl | 38 ++++++++++++++++++ testsuite/vpi/vpi001/testsuite.sh | 24 ++++++++++++ testsuite/vpi/vpi001/vpi1.c | 65 +++++++++++++++++++++++++++++++ testsuite/vpi/vpi002/mydesign.vhdl | 46 ++++++++++++++++++++++ testsuite/vpi/vpi002/testsuite.sh | 28 +++++++++++++ testsuite/vpi/vpi002/vpi1.c | 80 ++++++++++++++++++++++++++++++++++++++ testsuite/vpi/vpi003/mydesign.vhdl | 30 ++++++++++++++ testsuite/vpi/vpi003/testsuite.sh | 28 +++++++++++++ testsuite/vpi/vpi003/vpi1.c | 55 ++++++++++++++++++++++++++ 16 files changed, 524 insertions(+), 15 deletions(-) create mode 100755 testsuite/vpi/testsuite.sh create mode 100644 testsuite/vpi/vpi001/mydesign.vhdl create mode 100755 testsuite/vpi/vpi001/testsuite.sh create mode 100644 testsuite/vpi/vpi001/vpi1.c create mode 100644 testsuite/vpi/vpi002/mydesign.vhdl create mode 100755 testsuite/vpi/vpi002/testsuite.sh create mode 100644 testsuite/vpi/vpi002/vpi1.c create mode 100644 testsuite/vpi/vpi003/mydesign.vhdl create mode 100755 testsuite/vpi/vpi003/testsuite.sh create mode 100644 testsuite/vpi/vpi003/vpi1.c 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 +#include +#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 '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 +#include +#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 +#include +#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