OpenCores
URL https://opencores.org/ocsvn/viterbi_decoder_axi4s/viterbi_decoder_axi4s/trunk

Subversion Repositories viterbi_decoder_axi4s

[/] [viterbi_decoder_axi4s/] [trunk/] [src/] [acs.vhd] - Diff between revs 2 and 6

Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 6
--!
--!
--! Copyright (C) 2011 - 2012 Creonic GmbH
--! Copyright (C) 2011 - 2014 Creonic GmbH
--!
--!
--! This file is part of the Creonic Viterbi Decoder, which is distributed
--! This file is part of the Creonic Viterbi Decoder, which is distributed
--! under the terms of the GNU General Public License version 2.
--! under the terms of the GNU General Public License version 2.
--!
--!
--! @file
--! @file
--! @brief  Add-compare-select unit for trellis processing.
--! @brief  Add-compare-select unit for trellis processing.
--! @author Markus Fehrenz
--! @author Markus Fehrenz
--! @date   2011/07/04
--! @date   2011/07/04
--!
--!
--! @details The ACS decides which path is the the surviving trellis path.
--! @details The ACS decides which path is the the surviving trellis path.
--! In the design there are 2^{K-1} ACS instances.
--! In the design there are 2^{K-1} ACS instances.
--!
--!
 
 
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std.all;
 
 
library dec_viterbi;
library dec_viterbi;
use dec_viterbi.pkg_param.all;
use dec_viterbi.pkg_param.all;
use dec_viterbi.pkg_param_derived.all;
use dec_viterbi.pkg_param_derived.all;
use dec_viterbi.pkg_types.all;
use dec_viterbi.pkg_types.all;
use dec_viterbi.pkg_helper.all;
use dec_viterbi.pkg_helper.all;
 
 
 
 
entity acs is
entity acs is
        generic(
        generic(
 
 
                -- Reset value
                -- Reset value
                INITIALIZE_VALUE : in signed(BW_MAX_PROBABILITY - 1 downto 0)
                INITIALIZE_VALUE : in signed(BW_MAX_PROBABILITY - 1 downto 0)
        );
        );
        port(
        port(
                clk : in std_logic;
                clk : in std_logic;
                rst : in std_logic;
                rst : in std_logic;
 
 
                --
                --
                -- Values from branch distance, signed values in std_logic_vector
                -- Values from branch distance, signed values in std_logic_vector
                -- high is located in the upper half.
                -- high is located in the upper half.
                --
                --
                s_axis_inbranch_tvalid     : in  std_logic;
                s_axis_inbranch_tvalid     : in  std_logic;
                s_axis_inbranch_tdata_low  : in  std_logic_vector(BW_BRANCH_RESULT - 1 downto 0);
                s_axis_inbranch_tdata_low  : in  std_logic_vector(BW_BRANCH_RESULT - 1 downto 0);
                s_axis_inbranch_tdata_high : in  std_logic_vector(BW_BRANCH_RESULT - 1 downto 0);
                s_axis_inbranch_tdata_high : in  std_logic_vector(BW_BRANCH_RESULT - 1 downto 0);
                s_axis_inbranch_tlast      : in  std_logic;
                s_axis_inbranch_tlast      : in  std_logic;
                s_axis_inbranch_tready     : out std_logic;
                s_axis_inbranch_tready     : out std_logic;
 
 
                --
                --
                -- Probabilities from previous nodes, signed values in std_logic_vector
                -- Probabilities from previous nodes, signed values in std_logic_vector
                -- high is located in the upper half.
                -- high is located in the upper half.
                --
                --
                s_axis_inprev_tvalid     : in  std_logic;
                s_axis_inprev_tvalid     : in  std_logic;
                s_axis_inprev_tdata_low  : in  std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
                s_axis_inprev_tdata_low  : in  std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
                s_axis_inprev_tdata_high : in  std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
                s_axis_inprev_tdata_high : in  std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
                s_axis_inprev_tready     : out std_logic;
                s_axis_inprev_tready     : out std_logic;
 
 
                -- probability result of the add compare and select
                -- probability result of the add compare and select
                m_axis_outprob_tvalid  : out std_logic;
                m_axis_outprob_tvalid  : out std_logic;
                m_axis_outprob_tdata   : out std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
                m_axis_outprob_tdata   : out std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
                m_axis_outprob_tready  : in  std_logic;
                m_axis_outprob_tready  : in  std_logic;
 
 
                -- decision result of the add compare and select
                -- decision result of the add compare and select
                m_axis_outdec_tvalid   : out std_logic;
                m_axis_outdec_tvalid   : out std_logic;
                m_axis_outdec_tdata    : out std_logic;
                m_axis_outdec_tdata    : out std_logic;
                m_axis_outdec_tlast    : out std_logic;
                m_axis_outdec_tlast    : out std_logic;
                m_axis_outdec_tready   : in  std_logic
                m_axis_outdec_tready   : in  std_logic
        );
        );
end entity acs;
end entity acs;
 
 
 
 
architecture rtl of acs is
architecture rtl of acs is
 
 
        signal s_axis_inbranch_tlast_d : std_logic;
        signal s_axis_inbranch_tlast_d : std_logic;
        signal m_axis_outdec_tvalid_int : std_logic;
        signal m_axis_outdec_tvalid_int : std_logic;
        signal s_axis_inbranch_tready_int : std_logic;
        signal s_axis_inbranch_tready_int : std_logic;
 
 
begin
begin
 
 
        s_axis_inbranch_tready_int <= '1' when m_axis_outdec_tready = '1' or m_axis_outdec_tvalid_int = '0' else
        s_axis_inbranch_tready_int <= '1' when m_axis_outdec_tready = '1' or m_axis_outdec_tvalid_int = '0' else
                                      '0';
                                      '0';
        s_axis_inbranch_tready <= s_axis_inbranch_tready_int;
        s_axis_inbranch_tready <= s_axis_inbranch_tready_int;
        m_axis_outdec_tvalid   <= m_axis_outdec_tvalid_int;
        m_axis_outdec_tvalid   <= m_axis_outdec_tvalid_int;
 
 
        -- Add branch to previous, compare both paths and select survivor.
        -- Add branch to previous, compare both paths and select survivor.
        pr_add_compare : process(clk) is
        pr_add_compare : process(clk) is
                variable v_diff, v_high, v_low : signed(BW_MAX_PROBABILITY - 1 downto 0);
                variable v_diff, v_high, v_low : signed(BW_MAX_PROBABILITY - 1 downto 0);
        begin
        begin
        if rising_edge(clk) then
        if rising_edge(clk) then
                if rst = '1' then
                if rst = '1' then
                        m_axis_outdec_tvalid_int <= '0';
                        m_axis_outdec_tvalid_int <= '0';
                        m_axis_outdec_tdata      <= '0';
                        m_axis_outdec_tdata      <= '0';
                        m_axis_outdec_tlast      <= '0';
                        m_axis_outdec_tlast      <= '0';
 
                        m_axis_outprob_tvalid    <= '0';
                        s_axis_inprev_tready     <= '0';
                        s_axis_inprev_tready     <= '0';
                        s_axis_inbranch_tlast_d  <= '0';
                        s_axis_inbranch_tlast_d  <= '0';
                        m_axis_outprob_tdata     <= std_logic_vector(INITIALIZE_VALUE);
                        m_axis_outprob_tdata     <= std_logic_vector(INITIALIZE_VALUE);
                else
                else
                        -- If this is the last value, prepare for processing of next incoming value.
                        -- If this is the last value, prepare for processing of next incoming value.
                        if s_axis_inbranch_tlast_d = '1' then
                        if s_axis_inbranch_tlast_d = '1' then
                                m_axis_outprob_tdata     <= std_logic_vector(INITIALIZE_VALUE);
                                m_axis_outprob_tdata     <= std_logic_vector(INITIALIZE_VALUE);
                                s_axis_inbranch_tlast_d  <= '0';
                                s_axis_inbranch_tlast_d  <= '0';
                                m_axis_outdec_tvalid_int <= '0';
                                m_axis_outdec_tvalid_int <= '0';
                        end if;
                        end if;
 
                        if m_axis_outdec_tvalid_int = '1' and m_axis_outdec_tready = '1' then
 
                                m_axis_outdec_tvalid_int <= '0';
 
                        end if;
 
 
                        -- Process only if we receive valid data.
                        -- Process only if we receive valid data.
                        if s_axis_inbranch_tvalid = '1' and s_axis_inbranch_tready_int = '1' then
                        if s_axis_inbranch_tvalid = '1' and s_axis_inbranch_tready_int = '1' then
                                s_axis_inbranch_tlast_d <= s_axis_inbranch_tlast;
                                s_axis_inbranch_tlast_d <= s_axis_inbranch_tlast;
 
 
                                -- Add.
                                -- Add.
                                v_low  := signed(s_axis_inbranch_tdata_low)  + signed(s_axis_inprev_tdata_low);
                                v_low  := signed(s_axis_inbranch_tdata_low)  + signed(s_axis_inprev_tdata_low);
                                v_high := signed(s_axis_inbranch_tdata_high) + signed(s_axis_inprev_tdata_high);
                                v_high := signed(s_axis_inbranch_tdata_high) + signed(s_axis_inprev_tdata_high);
 
 
                                -- Use modulo normalization, do not extend the sign here!
                                -- Use modulo normalization, do not extend the sign here!
                                v_diff := v_low - v_high;
                                v_diff := v_low - v_high;
 
 
                                -- Compare, select the correct path.
                                -- Compare, select the correct path.
                                if v_diff < 0 then
                                if v_diff < 0 then
                                        m_axis_outdec_tdata  <= '1';
                                        m_axis_outdec_tdata  <= '1';
                                        m_axis_outprob_tdata <= std_logic_vector(v_high);
                                        m_axis_outprob_tdata <= std_logic_vector(v_high);
                                else
                                else
                                        m_axis_outdec_tdata  <= '0';
                                        m_axis_outdec_tdata  <= '0';
                                        m_axis_outprob_tdata <= std_logic_vector(v_low);
                                        m_axis_outprob_tdata <= std_logic_vector(v_low);
                                end if;
                                end if;
                                m_axis_outdec_tvalid_int <= s_axis_inbranch_tvalid;
                                m_axis_outdec_tvalid_int <= '1';
                        end if;
                        end if;
 
 
                        m_axis_outdec_tlast    <= s_axis_inbranch_tlast;
                        m_axis_outdec_tlast    <= s_axis_inbranch_tlast;
                end if;
                end if;
        end if;
        end if;
        end process pr_add_compare;
        end process pr_add_compare;
 
 
end architecture rtl;
end architecture rtl;
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.