Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

lustrec-tests / vhdl_json / vhdl_files / 2-exportOK / ghdl / ghdl / testsuite / gna / issue301 / src / acs.vhd @ 2051e520

History | View | Annotate | Download (4.23 KB)

1
--!
2
--! Copyright (C) 2011 - 2014 Creonic GmbH
3
--!
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
			m_axis_outprob_tvalid    <= '0';
93
			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
				m_axis_outdec_tvalid_int <= '0';
102
			end if;
103
			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

    
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
				m_axis_outdec_tvalid_int <= '1';
127
			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;