diff options
Diffstat (limited to 'testsuite/gna/issue301/src/recursion.vhd')
-rw-r--r-- | testsuite/gna/issue301/src/recursion.vhd | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/testsuite/gna/issue301/src/recursion.vhd b/testsuite/gna/issue301/src/recursion.vhd new file mode 100644 index 000000000..932058653 --- /dev/null +++ b/testsuite/gna/issue301/src/recursion.vhd @@ -0,0 +1,96 @@ +--! +--! Copyright (C) 2011 - 2014 Creonic GmbH +--! +--! This file is part of the Creonic Viterbi Decoder, which is distributed +--! under the terms of the GNU General Public License version 2. +--! +--! @file +--! @brief Recursion unit for recursive code. +--! @author Markus Fehrenz +--! @date 2011/01/12 +--! +--! @details The recusion handling buffers the reorder ouput and +--! calculates the correct output depending on the feedback polynomial. +--! + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library dec_viterbi; +use dec_viterbi.pkg_param.all; +use dec_viterbi.pkg_param_derived.all; + +entity recursionx is + port( + clk : in std_logic; + rst : in std_logic; + + -- + -- Decoded bits input from the reordering units in std_logic + -- + s_axis_input_tvalid : in std_logic; + s_axis_input_tdata : in std_logic; + s_axis_input_tlast : in std_logic; + s_axis_input_tready : out std_logic; + + -- + -- Output decoded bits convolved with the feedback polynomial + -- + m_axis_output_tvalid : out std_logic; + m_axis_output_tdata : out std_logic; + m_axis_output_tlast : out std_logic; + m_axis_output_tready : in std_logic + ); +end entity recursionx; + +architecture rtl of recursionx is + signal recursion_sreg : unsigned(ENCODER_MEMORY_DEPTH downto 0); + signal s_axis_input_tready_int : std_logic; + signal m_axis_output_tvalid_int : std_logic; + +begin + s_axis_input_tready_int <= '1' when m_axis_output_tready = '1' or m_axis_output_tvalid_int = '0' else + '0'; + + s_axis_input_tready <= s_axis_input_tready_int; + m_axis_output_tvalid <= m_axis_output_tvalid_int; + + -- Use the feedback polynomial to convolve the global path. + pr_recursion : process(clk) is + variable v_bit : std_logic := '0'; + variable v_recursion_state : unsigned(ENCODER_MEMORY_DEPTH downto 0); + begin + if rising_edge(clk) then + if rst = '1' then + recursion_sreg <= (others => '0'); + m_axis_output_tdata <= '0'; + m_axis_output_tlast <= '0'; + else + m_axis_output_tvalid_int <= s_axis_input_tvalid; + + if s_axis_input_tvalid = '1' and s_axis_input_tready_int = '1' then + + -- move current decoded output bits into shift register and reset if last flag is valid + if s_axis_input_tlast = '1' then + recursion_sreg <= (others => '0'); + else + recursion_sreg <= s_axis_input_tdata & recursion_sreg(ENCODER_MEMORY_DEPTH downto 1); + end if; + + -- convolve with feedback polynomial with the output register. + v_bit := '0'; + v_recursion_state := (s_axis_input_tdata & recursion_sreg(ENCODER_MEMORY_DEPTH downto 1)) and + ('1' & to_unsigned(FEEDBACK_POLYNOMIAL, ENCODER_MEMORY_DEPTH)); + for i in ENCODER_MEMORY_DEPTH downto 0 loop + v_bit := v_bit xor v_recursion_state(i); + end loop; + m_axis_output_tdata <= v_bit; + + m_axis_output_tlast <= s_axis_input_tlast; + end if; + end if; + end if; + end process pr_recursion; + +end architecture rtl; |