diff options
-rw-r--r-- | testsuite/gna/issue531/repro1.vhdl | 67 | ||||
-rw-r--r-- | testsuite/gna/issue531/sample_slice_ports.vhd | 50 | ||||
-rw-r--r-- | testsuite/gna/issue531/submod.vhd | 24 | ||||
-rw-r--r-- | testsuite/gna/issue531/test.py | 32 | ||||
-rwxr-xr-x | testsuite/gna/issue531/testsuite.sh | 28 | ||||
-rw-r--r-- | testsuite/gna/issue531/vpi1.c | 114 |
6 files changed, 315 insertions, 0 deletions
diff --git a/testsuite/gna/issue531/repro1.vhdl b/testsuite/gna/issue531/repro1.vhdl new file mode 100644 index 000000000..7cf8e3c65 --- /dev/null +++ b/testsuite/gna/issue531/repro1.vhdl @@ -0,0 +1,67 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +entity submodule is +port ( + clk : in std_logic; + arg : in std_logic_vector(7 downto 0); + res : out std_logic_vector(7 downto 0) +); +end submodule; + +architecture rtl of submodule is +begin + sub_proc : process(clk) + variable last : std_logic_vector(7 downto 0); + begin + if rising_edge(clk) then + res <= arg XOR last; + last := arg; + end if; + end process sub_proc; + + monitor : process(clk) + begin + if rising_edge(clk) then + report "arg: " & integer'image(to_integer(unsigned(arg))); + end if; + end process; +end rtl; + + +library ieee; + use ieee.std_logic_1164.all; + +entity sliced_ex is +port ( + arg_a : in std_logic_vector(3 downto 0); + arg_b : in std_logic_vector(3 downto 0) +); +end sliced_ex; + +architecture rtl of sliced_ex is + signal clk : std_logic; +begin + process + begin + clk <= '0'; + for i in 1 to 5 * 2 loop + wait for 10 ns; + clk <= not clk; + end loop; + wait; + end process; + + sub_module : entity work.submodule + port map ( + clk => clk, + + -- This one fails + arg(3 downto 0) => arg_a(3 downto 0), + arg(7 downto 4) => arg_b(3 downto 0), + + res => OPEN + ); + +end rtl; diff --git a/testsuite/gna/issue531/sample_slice_ports.vhd b/testsuite/gna/issue531/sample_slice_ports.vhd new file mode 100644 index 000000000..4cf623c5b --- /dev/null +++ b/testsuite/gna/issue531/sample_slice_ports.vhd @@ -0,0 +1,50 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +entity sliced_ex is +port ( + clk : in std_logic; + reset : in std_logic; + arg_a : in std_logic_vector(3 downto 0); + arg_b : in std_logic_vector(3 downto 0) +); +end sliced_ex; + +architecture rtl of sliced_ex is + + signal aa, ab : std_logic_vector(3 downto 0); + +begin + + aa <= arg_a(aa'range); + ab <= arg_b(ab'range); + + monitor : process(clk) + begin + if rising_edge(clk) then + report "arg_a: " & integer'image(to_integer(unsigned(arg_a))) + & ", arg_b: " & integer'image(to_integer(unsigned(arg_b))); + end if; + end process; + + sub_module : entity work.submodule + port map ( + clk => clk, + + -- This version works + --arg( 7 downto 0) => aa, + --arg(15 downto 8) => ab, + + -- This one works + --arg => arg_a, + + -- This one fails + arg(3 downto 0) => arg_a(3 downto 0), + arg(7 downto 4) => arg_b(3 downto 0), + + res => OPEN + ); + +end rtl; + diff --git a/testsuite/gna/issue531/submod.vhd b/testsuite/gna/issue531/submod.vhd new file mode 100644 index 000000000..e3d3c2af7 --- /dev/null +++ b/testsuite/gna/issue531/submod.vhd @@ -0,0 +1,24 @@ +library ieee; + use ieee.std_logic_1164.all; + +entity submodule is +port ( + clk : in std_logic; + arg : in std_logic_vector(7 downto 0); + res : out std_logic_vector(7 downto 0) +); +end submodule; + +architecture rtl of submodule is +begin + sub_proc : process(clk) + variable last : std_logic_vector(7 downto 0); + begin + if rising_edge(clk) then + res <= arg XOR last; + last := arg; + end if; + end process sub_proc; +end rtl; + + diff --git a/testsuite/gna/issue531/test.py b/testsuite/gna/issue531/test.py new file mode 100644 index 000000000..5a3c55678 --- /dev/null +++ b/testsuite/gna/issue531/test.py @@ -0,0 +1,32 @@ +#!/usr/bin/python2.7 +from __future__ import print_function + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import Timer, RisingEdge + +@cocotb.test(timeout=None) +def proto(dut): + CLK_PERIOD = 15 + + dut.arg_a <= 0 + dut.arg_b <= 0 + + dut_clk = Clock(dut.clk, CLK_PERIOD, 'ns') + clk = cocotb.fork(dut_clk.start()) + + dut.reset <= 1 + for i in range(2): + yield RisingEdge(dut.clk) + dut.reset <= 0 + for i in range(2): + yield RisingEdge(dut.clk) + yield Timer(1) + dut.arg_a <= 8 + dut.arg_b <= 6 + for i in range(5): + yield RisingEdge(dut.clk) + print('Value in dut:', dut.sub_module.arg.value) + yield Timer(1) + dut.arg_a <= 8 + i + dut.arg_b <= 6 - i diff --git a/testsuite/gna/issue531/testsuite.sh b/testsuite/gna/issue531/testsuite.sh new file mode 100755 index 000000000..4b2ee49aa --- /dev/null +++ b/testsuite/gna/issue531/testsuite.sh @@ -0,0 +1,28 @@ +#! /bin/sh + +. ../../testenv.sh + +analyze repro1.vhdl +elab sliced_ex + +if ghdl_has_feature sliced_ex vpi; then + $GHDL --vpi-compile -v gcc -c vpi1.c + $GHDL --vpi-link -v gcc -o vpi1.vpi vpi1.o + + if [ "$OS" = "Windows_NT" ]; then + vpi_lib=`$GHDL --vpi-library-dir | sed -e 's!\\\\!/!g' -e 's!^C:!/C!g'` + echo vpi_lib: $vpi_lib + PATH="$PATH:$vpi_lib" + fi + + simulate sliced_ex --vpi=./vpi1.vpi | tee sliced_ex.out + if grep -q Error sliced_ex.out; then + echo "Error in output" + exit 1; + fi + + rm -f vpi1.vpi vpi1.o sliced_ex.out +fi +clean + +echo "Test successful" diff --git a/testsuite/gna/issue531/vpi1.c b/testsuite/gna/issue531/vpi1.c new file mode 100644 index 000000000..a555ee4d6 --- /dev/null +++ b/testsuite/gna/issue531/vpi1.c @@ -0,0 +1,114 @@ +#include <stdio.h> +#include <string.h> +#include <vpi_user.h> + +struct net_descs +{ + const char *name; + vpiHandle *handle; +}; + +static vpiHandle clk, arg_a, arg_b, res; +static int cnt; + +static struct net_descs nets[] = { + { "sliced_ex.clk", &clk}, + { "sliced_ex.arg_a", &arg_a}, + { "sliced_ex.arg_b", &arg_b}, + { "sliced_ex.sub_module.res", &res}, + { NULL, NULL} +}; + +static PLI_INT32 +vpi_clk_proc(p_cb_data data) +{ + s_vpi_value val; + + val.format = vpiBinStrVal; + vpi_get_value (clk, &val); + /* Detect edge. */ + if (strcmp (val.value.str, "1") != 0) + return 0; + + val.format = vpiBinStrVal; + vpi_get_value (res, &val); + printf ("cycle %d: res = %s\n", cnt, val.value.str); + + switch (cnt) + { + case 0: + val.format = vpiBinStrVal; + val.value.str = "0001"; + vpi_put_value (arg_a, &val, NULL, vpiNoDelay); + val.format = vpiBinStrVal; + val.value.str = "0010"; + vpi_put_value (arg_b, &val, NULL, vpiNoDelay); + break; + case 2: + val.format = vpiBinStrVal; + val.value.str = "0010"; + vpi_put_value (arg_a, &val, NULL, vpiNoDelay); + val.format = vpiBinStrVal; + val.value.str = "0011"; + vpi_put_value (arg_b, &val, NULL, vpiNoDelay); + break; + case 3: + if (strcmp(val.value.str, "00000000") != 0) + printf ("Error!\n"); + break; + case 4: + if (strcmp(val.value.str, "00010011") != 0) + printf ("Error!\n"); + break; + default: + break; + } + + cnt++; + return 0; +} + +static PLI_INT32 +vpi_start_proc(p_cb_data data) +{ + s_vpi_value val; + s_cb_data cb; + int i; + + for (i = 0; nets[i].name; i++) + { + *nets[i].handle = vpi_handle_by_name ((char *)nets[i].name, NULL); + if (*nets[i].handle == NULL) + { + printf ("cannot get net %s\n", nets[i].name); + 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"); + + return 0; +} + +static void +my_handle_register(void) +{ + s_cb_data cb; + + cb.reason = cbStartOfSimulation; + cb.cb_rtn = &vpi_start_proc; + cb.user_data = NULL; + if (vpi_register_cb (&cb) == NULL) + vpi_printf ("cannot register EndStartOfSimulation call back\n"); +} + +void (*vlog_startup_routines[]) () = +{ + my_handle_register, + 0 +}; |