aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2021-06-10 07:57:35 +0200
committerTristan Gingold <tgingold@free.fr>2021-06-10 07:57:35 +0200
commit46a2c6d28d57b17b52183d1ab9f4244661f97892 (patch)
tree8feae9b3c4fa616ef2687148d67e4a221fe68957 /testsuite
parentc64e7ba56376b933cb0ddb2b4949a83c926a3c67 (diff)
downloadghdl-46a2c6d28d57b17b52183d1ab9f4244661f97892.tar.gz
ghdl-46a2c6d28d57b17b52183d1ab9f4244661f97892.tar.bz2
ghdl-46a2c6d28d57b17b52183d1ab9f4244661f97892.zip
testsuite/gna: add reproducer for #237
Diffstat (limited to 'testsuite')
-rw-r--r--testsuite/gna/issue237/test_array.vhdl34
-rwxr-xr-xtestsuite/gna/issue237/testsuite.sh20
-rw-r--r--testsuite/gna/issue237/vpi1.c132
3 files changed, 186 insertions, 0 deletions
diff --git a/testsuite/gna/issue237/test_array.vhdl b/testsuite/gna/issue237/test_array.vhdl
new file mode 100644
index 000000000..2351f09d3
--- /dev/null
+++ b/testsuite/gna/issue237/test_array.vhdl
@@ -0,0 +1,34 @@
+library ieee ;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity test_array is
+end;
+
+architecture RTL of test_array is
+ type mem_t is array (natural range <>) of std_logic_vector(31 downto 0);
+ signal mem_down : mem_t(7 downto 0);
+ signal num : natural := 0;
+ signal clk : std_logic;
+begin
+ process
+ begin
+ for i in 1 to 4 loop
+ num <= i;
+ clk <= '0';
+ wait for 1 ns;
+ clk <= '1';
+ wait for 1 ns;
+ end loop;
+ wait;
+ end process;
+
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ for i in mem_down'range loop
+ mem_down (i) <= std_logic_vector (to_unsigned (i, 32));
+ end loop;
+ end if;
+ end process;
+end RTL;
diff --git a/testsuite/gna/issue237/testsuite.sh b/testsuite/gna/issue237/testsuite.sh
new file mode 100755
index 000000000..de9170e1b
--- /dev/null
+++ b/testsuite/gna/issue237/testsuite.sh
@@ -0,0 +1,20 @@
+#! /bin/sh
+
+. ../../testenv.sh
+
+analyze test_array.vhdl
+elab test_array
+
+if c_compiler_is_available && ghdl_has_feature test_array vpi; then
+ add_vpi_path
+
+ $GHDL --vpi-compile -v gcc $CFLAGS -c vpi1.c
+ $GHDL --vpi-link -v gcc $CFLAGS -o vpi1.vpi vpi1.o
+
+ simulate test_array --vpi=./vpi1.vpi
+
+ rm -f vpi1.vpi vpi1.o
+fi
+clean
+
+echo "Test successful"
diff --git a/testsuite/gna/issue237/vpi1.c b/testsuite/gna/issue237/vpi1.c
new file mode 100644
index 000000000..873dc25bc
--- /dev/null
+++ b/testsuite/gna/issue237/vpi1.c
@@ -0,0 +1,132 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vpi_user.h>
+
+static vpiHandle clk;
+static unsigned cycle;
+
+static void
+show_value (const char *name)
+{
+ vpiHandle net;
+ vpiHandle rng;
+ vpiHandle el;
+ s_vpi_value val;
+ int left, right;
+ int i;
+
+ net = vpi_handle_by_name ((char *)name, NULL);
+ if (net == NULL)
+ {
+ printf ("cannot get net: %s\n", name);
+ exit(1);
+ return;
+ }
+
+ /* Get range. */
+ rng = vpi_handle (vpiLeftRange, net);
+ val.format = vpiIntVal;
+ vpi_get_value (rng, &val);
+ left = val.value.integer;
+
+ rng = vpi_handle (vpiRightRange, net);
+ val.format = vpiIntVal;
+ vpi_get_value (rng, &val);
+ right = val.value.integer;
+
+ printf ("%s[%d:%d]\n", name, left, right);
+
+ i = left;
+ while (1) {
+ el = vpi_handle_by_index (net, i);
+ if (el == NULL)
+ val.value.str = "ERROR";
+ else {
+ val.format = vpiBinStrVal;
+ vpi_get_value (el, &val);
+ }
+ printf ("%s[%d] = %s", name, i, val.value.str);
+ if (el != NULL) {
+ val.format = vpiIntVal;
+ vpi_get_value (el, &val);
+ printf (" = %d", val.value.integer);
+ }
+ putchar('\n');
+ if (el == NULL || val.value.integer != i)
+ exit (1);
+ if (i == right)
+ break;
+ if (left < right)
+ i++;
+ else
+ i--;
+ }
+
+#if 0
+ val.format = vpiBinStrVal;
+ vpi_get_value (net, &val);
+ printf ("%s= %s\n", name, val.value.str);
+#endif
+}
+
+static PLI_INT32
+vpi_clk_proc (struct t_cb_data *cb)
+{
+ s_vpi_value val;
+
+ val.format = vpiBinStrVal;
+ vpi_get_value (clk, &val);
+ /* Detect edge. */
+ if (strcmp (val.value.str, "1") != 0)
+ return 0;
+
+ cycle++;
+ printf ("clock cycle %d\n", cycle);
+
+ if (cycle == 2)
+ show_value ("test_array.mem_down");
+
+ return 0;
+}
+
+static PLI_INT32
+endofcompile_proc (struct t_cb_data *compile_cb)
+{
+ s_cb_data cb;
+
+ clk = vpi_handle_by_name ("test_array.clk", NULL);
+ if (clk == NULL)
+ {
+ printf ("cannot get net clk\n");
+ return 0;
+ }
+
+ cb.reason = cbValueChange;
+ cb.cb_rtn = &vpi_clk_proc;
+ cb.user_data = NULL;
+ cb.obj = clk;
+ if (vpi_register_cb (&cb) == NULL)
+ vpi_printf ("cannot register ValueChange call back\n");
+
+ cycle = 0;
+
+ return 0;
+}
+
+static void my_handle_register(void)
+{
+ s_cb_data cb;
+
+ cb.reason = cbEndOfCompile;
+ cb.cb_rtn = &endofcompile_proc;
+ cb.user_data = NULL;
+ if (vpi_register_cb (&cb) == NULL)
+ vpi_printf ("cannot register EndOfCompile call back\n");
+}
+
+void (*vlog_startup_routines[]) () =
+{
+ my_handle_register,
+ 0
+};