diff options
author | Tristan Gingold <tgingold@free.fr> | 2021-06-10 07:57:35 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2021-06-10 07:57:35 +0200 |
commit | 46a2c6d28d57b17b52183d1ab9f4244661f97892 (patch) | |
tree | 8feae9b3c4fa616ef2687148d67e4a221fe68957 /testsuite/gna/issue237/vpi1.c | |
parent | c64e7ba56376b933cb0ddb2b4949a83c926a3c67 (diff) | |
download | ghdl-46a2c6d28d57b17b52183d1ab9f4244661f97892.tar.gz ghdl-46a2c6d28d57b17b52183d1ab9f4244661f97892.tar.bz2 ghdl-46a2c6d28d57b17b52183d1ab9f4244661f97892.zip |
testsuite/gna: add reproducer for #237
Diffstat (limited to 'testsuite/gna/issue237/vpi1.c')
-rw-r--r-- | testsuite/gna/issue237/vpi1.c | 132 |
1 files changed, 132 insertions, 0 deletions
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 +}; |