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] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 mfehrenz
--!
2 6 mfehrenz
--! Copyright (C) 2011 - 2014 Creonic GmbH
3 2 mfehrenz
--!
4
--! This file is part of the Creonic Viterbi Decoder, which is distributed
5
--! under the terms of the GNU General Public License version 2.
6
--!
7
--! @file
8
--! @brief  Add-compare-select unit for trellis processing.
9
--! @author Markus Fehrenz
10
--! @date   2011/07/04
11
--!
12
--! @details The ACS decides which path is the the surviving trellis path.
13
--! In the design there are 2^{K-1} ACS instances.
14
--!
15
 
16
library ieee;
17
use ieee.std_logic_1164.all;
18
use ieee.numeric_std.all;
19
 
20
library dec_viterbi;
21
use dec_viterbi.pkg_param.all;
22
use dec_viterbi.pkg_param_derived.all;
23
use dec_viterbi.pkg_types.all;
24
use dec_viterbi.pkg_helper.all;
25
 
26
 
27
entity acs is
28
        generic(
29
 
30
                -- Reset value
31
                INITIALIZE_VALUE : in signed(BW_MAX_PROBABILITY - 1 downto 0)
32
        );
33
        port(
34
                clk : in std_logic;
35
                rst : in std_logic;
36
 
37
                --
38
                -- Values from branch distance, signed values in std_logic_vector
39
                -- high is located in the upper half.
40
                --
41
                s_axis_inbranch_tvalid     : in  std_logic;
42
                s_axis_inbranch_tdata_low  : in  std_logic_vector(BW_BRANCH_RESULT - 1 downto 0);
43
                s_axis_inbranch_tdata_high : in  std_logic_vector(BW_BRANCH_RESULT - 1 downto 0);
44
                s_axis_inbranch_tlast      : in  std_logic;
45
                s_axis_inbranch_tready     : out std_logic;
46
 
47
                --
48
                -- Probabilities from previous nodes, signed values in std_logic_vector
49
                -- high is located in the upper half.
50
                --
51
                s_axis_inprev_tvalid     : in  std_logic;
52
                s_axis_inprev_tdata_low  : in  std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
53
                s_axis_inprev_tdata_high : in  std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
54
                s_axis_inprev_tready     : out std_logic;
55
 
56
                -- probability result of the add compare and select
57
                m_axis_outprob_tvalid  : out std_logic;
58
                m_axis_outprob_tdata   : out std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
59
                m_axis_outprob_tready  : in  std_logic;
60
 
61
                -- decision result of the add compare and select
62
                m_axis_outdec_tvalid   : out std_logic;
63
                m_axis_outdec_tdata    : out std_logic;
64
                m_axis_outdec_tlast    : out std_logic;
65
                m_axis_outdec_tready   : in  std_logic
66
        );
67
end entity acs;
68
 
69
 
70
architecture rtl of acs is
71
 
72
        signal s_axis_inbranch_tlast_d : std_logic;
73
        signal m_axis_outdec_tvalid_int : std_logic;
74
        signal s_axis_inbranch_tready_int : std_logic;
75
 
76
begin
77
 
78
        s_axis_inbranch_tready_int <= '1' when m_axis_outdec_tready = '1' or m_axis_outdec_tvalid_int = '0' else
79
                                      '0';
80
        s_axis_inbranch_tready <= s_axis_inbranch_tready_int;
81
        m_axis_outdec_tvalid   <= m_axis_outdec_tvalid_int;
82
 
83
        -- Add branch to previous, compare both paths and select survivor.
84
        pr_add_compare : process(clk) is
85
                variable v_diff, v_high, v_low : signed(BW_MAX_PROBABILITY - 1 downto 0);
86
        begin
87
        if rising_edge(clk) then
88
                if rst = '1' then
89
                        m_axis_outdec_tvalid_int <= '0';
90
                        m_axis_outdec_tdata      <= '0';
91
                        m_axis_outdec_tlast      <= '0';
92 6 mfehrenz
                        m_axis_outprob_tvalid    <= '0';
93 2 mfehrenz
                        s_axis_inprev_tready     <= '0';
94
                        s_axis_inbranch_tlast_d  <= '0';
95
                        m_axis_outprob_tdata     <= std_logic_vector(INITIALIZE_VALUE);
96
                else
97
                        -- If this is the last value, prepare for processing of next incoming value.
98
                        if s_axis_inbranch_tlast_d = '1' then
99
                                m_axis_outprob_tdata     <= std_logic_vector(INITIALIZE_VALUE);
100
                                s_axis_inbranch_tlast_d  <= '0';
101 6 mfehrenz
                                m_axis_outdec_tvalid_int <= '0';
102 2 mfehrenz
                        end if;
103 6 mfehrenz
                        if m_axis_outdec_tvalid_int = '1' and m_axis_outdec_tready = '1' then
104
                                m_axis_outdec_tvalid_int <= '0';
105
                        end if;
106 2 mfehrenz
 
107
                        -- Process only if we receive valid data.
108
                        if s_axis_inbranch_tvalid = '1' and s_axis_inbranch_tready_int = '1' then
109
                                s_axis_inbranch_tlast_d <= s_axis_inbranch_tlast;
110
 
111
                                -- Add.
112
                                v_low  := signed(s_axis_inbranch_tdata_low)  + signed(s_axis_inprev_tdata_low);
113
                                v_high := signed(s_axis_inbranch_tdata_high) + signed(s_axis_inprev_tdata_high);
114
 
115
                                -- Use modulo normalization, do not extend the sign here!
116
                                v_diff := v_low - v_high;
117
 
118
                                -- Compare, select the correct path.
119
                                if v_diff < 0 then
120
                                        m_axis_outdec_tdata  <= '1';
121
                                        m_axis_outprob_tdata <= std_logic_vector(v_high);
122
                                else
123
                                        m_axis_outdec_tdata  <= '0';
124
                                        m_axis_outprob_tdata <= std_logic_vector(v_low);
125
                                end if;
126 6 mfehrenz
                                m_axis_outdec_tvalid_int <= '1';
127 2 mfehrenz
                        end if;
128
 
129
                        m_axis_outdec_tlast    <= s_axis_inbranch_tlast;
130
                end if;
131
        end if;
132
        end process pr_add_compare;
133
 
134
end architecture rtl;

powered by: WebSVN 2.1.0

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