From 46a2c6d28d57b17b52183d1ab9f4244661f97892 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Thu, 10 Jun 2021 07:57:35 +0200 Subject: testsuite/gna: add reproducer for #237 --- testsuite/gna/issue237/test_array.vhdl | 34 +++++++++ testsuite/gna/issue237/testsuite.sh | 20 +++++ testsuite/gna/issue237/vpi1.c | 132 +++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 testsuite/gna/issue237/test_array.vhdl create mode 100755 testsuite/gna/issue237/testsuite.sh create mode 100644 testsuite/gna/issue237/vpi1.c 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 +#include +#include +#include + +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 +}; -- cgit v1.2.3