diff options
-rw-r--r-- | testsuite/synth/issue412/generic_pkg.vhdl | 42 | ||||
-rw-r--r-- | testsuite/synth/issue412/generic_sfifo-orig.vhdl | 88 | ||||
-rw-r--r-- | testsuite/synth/issue412/generic_sfifo.vhdl | 88 | ||||
-rw-r--r-- | testsuite/synth/issue412/my_fifo.vhdl | 31 | ||||
-rw-r--r-- | testsuite/synth/issue412/tb_my_fifo.vhdl | 66 | ||||
-rwxr-xr-x | testsuite/synth/issue412/testsuite.sh | 13 |
6 files changed, 328 insertions, 0 deletions
diff --git a/testsuite/synth/issue412/generic_pkg.vhdl b/testsuite/synth/issue412/generic_pkg.vhdl new file mode 100644 index 000000000..3a97c2961 --- /dev/null +++ b/testsuite/synth/issue412/generic_pkg.vhdl @@ -0,0 +1,42 @@ +-- package containing a type-generic D Flip Flop +-- may not be 100% valid VHDL code, contact ktbarrett on gitter +-- non-generic version does synthesize correctly +package generic_pkg is + + procedure generic_FF + generic ( + constant T: type) + paramater ( + signal q : out T; + signal d : in T; + signal clk : in std_logic; + signal rst : in std_logic; + constant INIT : in T; + signal en : in std_logic := '1'); + +end package generic_pkg; + +package body generic_pkg is + + procedure generic_FF + generic ( + constant T: type) + paramater ( + signal q : out T; + signal d : in T; + signal clk : in std_logic; + signal rst : in std_logic; + constant INIT : in T; + signal en : in std_logic := '1') + is + begin + if (rising_edge(clk)) then + if (rst /= '0') then + q <= INIT; + elsif (en = '1') then + q <= d; + end if; + end if; + end procedure generic_FF; + +end package body generic_pkg; diff --git a/testsuite/synth/issue412/generic_sfifo-orig.vhdl b/testsuite/synth/issue412/generic_sfifo-orig.vhdl new file mode 100644 index 000000000..d1ea90685 --- /dev/null +++ b/testsuite/synth/issue412/generic_sfifo-orig.vhdl @@ -0,0 +1,88 @@ +-- A simple type-generic stream-style synchronous FIFO +-- may not be 100% valid VHDL code, contact ktbarrett on gitter +-- non-generic version does synthesize correctly +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +entity generic_SFIFO is + generic ( + T : type; + MIN_DEPTH : natural); + port ( + clk : in std_ulogic; + rst : in std_ulogic; + data_in : in T; + valid_in : in std_ulogic; + ready_out : out std_ulogic; + data_out : out T; + valid_out : out std_ulogic; + ready_in : in std_ulogic); +end entity generic_SFIFO; + +architecture rtl of generic_SFIFO is + + function clog2 (n: natural) return natural is + variable i : natural; + variable test : natural; + begin + test := 1; + i := 0; + while (test < n) loop + i := i + 1; + test := test * 2; + end loop; + return i; + end function clog2; + + constant ptr_size : natural := clog2(MIN_DEPTH); + constant depth : natural := 2 ** ptr_size; + signal rd_ptr : unsigned(ptr_size downto 0); + signal wr_ptr : unsigned(ptr_size downto 0); + + type ram_type is array(0 to depth - 1) of T; + + signal ram : ram_type; + +begin + + fifo_proc : process (clk) is + + variable next_wr_ptr : wr_ptr'subtype; + variable next_rd_ptr : rd_ptr'subtype; + + begin + + if (rising_edge(clk)) then + if (rst /= '0') then + rd_ptr <= (others => '0'); + wr_ptr <= (others => '0'); + ready_out <= '0'; + valid_out <= '0'; + else + next_wr_ptr := wr_ptr; + next_rd_ptr := rd_ptr; + if ((valid_in='1') and (ready_out='1')) then + ram(to_integer(wr_ptr(wr_ptr'left - 1 downto 0))) <= data_in; + next_wr_ptr := wr_ptr + 1; + end if; + if ((valid_out='1') and (ready_in='1')) then + next_rd_ptr := rd_ptr + 1; + end if; + ready_out <= '0' when + (next_wr_ptr(next_wr_ptr'left) /= next_rd_ptr(next_rd_ptr'left)) and + (next_wr_ptr(next_wr_ptr'left - 1 downto 0) = next_rd_ptr(next_rd_ptr'left - 1 downto 0)) else + '1'; + valid_out <= '0' when + (wr_ptr(wr_ptr'left) = next_rd_ptr(next_rd_ptr'left)) and + (wr_ptr(wr_ptr'left - 1 downto 0) = next_rd_ptr(next_rd_ptr'left - 1 downto 0)) else + '1'; + wr_ptr <= next_wr_ptr; + rd_ptr <= next_rd_ptr; + data_out <= ram(to_integer(next_rd_ptr(next_rd_ptr'left - 1 downto 0))); + end if; + end if; + + end process fifo_proc; + +end architecture rtl; diff --git a/testsuite/synth/issue412/generic_sfifo.vhdl b/testsuite/synth/issue412/generic_sfifo.vhdl new file mode 100644 index 000000000..92e72a970 --- /dev/null +++ b/testsuite/synth/issue412/generic_sfifo.vhdl @@ -0,0 +1,88 @@ +-- A simple type-generic stream-style synchronous FIFO +-- may not be 100% valid VHDL code, contact ktbarrett on gitter +-- non-generic version does synthesize correctly +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +entity generic_SFIFO is + generic ( + type T; + MIN_DEPTH : natural); + port ( + clk : in std_ulogic; + rst : in std_ulogic; + data_in : in T; + valid_in : in std_ulogic; + ready_out : out std_ulogic; -- If true, can accept data + data_out : out T; + valid_out : out std_ulogic; + ready_in : in std_ulogic); -- To consume data +end entity generic_SFIFO; + +architecture rtl of generic_SFIFO is + + function clog2 (n: natural) return natural is + variable i : natural; + variable test : natural; + begin + test := 1; + i := 0; + while (test < n) loop + i := i + 1; + test := test * 2; + end loop; + return i; + end function clog2; + + constant ptr_size : natural := clog2(MIN_DEPTH); + constant depth : natural := 2 ** ptr_size; + signal rd_ptr : unsigned(ptr_size downto 0); + signal wr_ptr : unsigned(ptr_size downto 0); + + type ram_type is array(0 to depth - 1) of T; + + signal ram : ram_type; + +begin + + fifo_proc : process (clk) is + + variable next_wr_ptr : wr_ptr'subtype; + variable next_rd_ptr : rd_ptr'subtype; + + begin + + if (rising_edge(clk)) then + if (rst /= '0') then + rd_ptr <= (others => '0'); + wr_ptr <= (others => '0'); + ready_out <= '0'; + valid_out <= '0'; + else + next_wr_ptr := wr_ptr; + next_rd_ptr := rd_ptr; + if ((valid_in='1') and (ready_out='1')) then + ram(to_integer(wr_ptr(wr_ptr'left - 1 downto 0))) <= data_in; + next_wr_ptr := wr_ptr + 1; + end if; + if ((valid_out='1') and (ready_in='1')) then + next_rd_ptr := rd_ptr + 1; + end if; + ready_out <= '0' when + (next_wr_ptr(next_wr_ptr'left) /= next_rd_ptr(next_rd_ptr'left)) and + (next_wr_ptr(next_wr_ptr'left - 1 downto 0) = next_rd_ptr(next_rd_ptr'left - 1 downto 0)) else + '1'; + valid_out <= '0' when + (wr_ptr(wr_ptr'left) = next_rd_ptr(next_rd_ptr'left)) and + (wr_ptr(wr_ptr'left - 1 downto 0) = next_rd_ptr(next_rd_ptr'left - 1 downto 0)) else + '1'; + wr_ptr <= next_wr_ptr; + rd_ptr <= next_rd_ptr; + data_out <= ram(to_integer(next_rd_ptr(next_rd_ptr'left - 1 downto 0))); + end if; + end if; + + end process fifo_proc; + +end architecture rtl; diff --git a/testsuite/synth/issue412/my_fifo.vhdl b/testsuite/synth/issue412/my_fifo.vhdl new file mode 100644 index 000000000..c06f1a776 --- /dev/null +++ b/testsuite/synth/issue412/my_fifo.vhdl @@ -0,0 +1,31 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity my_FIFO is + port ( + clk : in std_ulogic; + rst : in std_ulogic; + data_in : in std_logic_vector(7 downto 0); + valid_in : in std_ulogic; + ready_out : out std_ulogic; + data_out : out std_logic_vector(7 downto 0); + valid_out : out std_ulogic; + ready_in : in std_ulogic); +end entity my_FIFO; + +architecture behav of my_fifo is +begin + inst: entity work.generic_sfifo + generic map ( + t => std_logic_vector (7 downto 0), + min_depth => 8) + port map ( + clk => clk, + rst => rst, + data_in => data_in, + valid_in => valid_in, + ready_out => ready_out, + data_out => data_out, + valid_out => valid_out, + ready_in => ready_in); +end behav; diff --git a/testsuite/synth/issue412/tb_my_fifo.vhdl b/testsuite/synth/issue412/tb_my_fifo.vhdl new file mode 100644 index 000000000..8f3def0de --- /dev/null +++ b/testsuite/synth/issue412/tb_my_fifo.vhdl @@ -0,0 +1,66 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity tb_my_FIFO is +end; + +architecture behav of tb_my_fifo is + signal clk : std_ulogic; + signal rst : std_ulogic; + signal data_in : std_logic_vector(7 downto 0); + signal valid_in : std_ulogic; + signal ready_out : std_ulogic; + signal data_out : std_logic_vector(7 downto 0); + signal valid_out : std_ulogic; + signal ready_in : std_ulogic; +begin + inst_my_FIFO: entity work.my_FIFO + port map ( + clk => clk, + rst => rst, + data_in => data_in, + valid_in => valid_in, + ready_out => ready_out, + data_out => data_out, + valid_out => valid_out, + ready_in => ready_in); + + process + procedure pulse is + begin + clk <= '0'; + wait for 5 ns; + clk <= '1'; + wait for 5 ns; + end pulse; + begin + rst <= '1'; + valid_in <= '0'; + ready_in <= '0'; + pulse; + + rst <= '0'; + pulse; + + assert valid_out = '0' severity failure; + assert ready_out = '1' severity failure; + + data_in <= x"d5"; + valid_in <= '1'; + pulse; + + valid_in <= '0'; + + -- Need a second cycle to see the data on the outputs. + pulse; + assert valid_out = '1' severity failure; + assert data_out = x"d5" severity failure; + + ready_in <= '1'; + pulse; + assert valid_out = '0' severity failure; + + ready_in <= '0'; + wait; + end process; +end behav; diff --git a/testsuite/synth/issue412/testsuite.sh b/testsuite/synth/issue412/testsuite.sh new file mode 100755 index 000000000..0fe7c9ba9 --- /dev/null +++ b/testsuite/synth/issue412/testsuite.sh @@ -0,0 +1,13 @@ +#! /bin/sh + +. ../../testenv.sh + +GHDL_STD_FLAGS=--std=08 + +synth generic_sfifo.vhdl my_fifo.vhdl -e > syn_my_fifo.vhdl + +analyze syn_my_fifo.vhdl tb_my_fifo.vhdl +elab_simulate tb_my_fifo +clean + +echo "Test successful" |