aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/gna/issue301/src/recursion.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/gna/issue301/src/recursion.vhd')
-rw-r--r--testsuite/gna/issue301/src/recursion.vhd96
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;