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

Subversion Repositories viterbi_decoder_axi4s

[/] [viterbi_decoder_axi4s/] [trunk/] [src/] [dec_viterbi.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 mfehrenz
--!
2
--! Copyright (C) 2011 - 2012 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  Viterbi decoder top entity, connecting all decoder units.
9
--! @author Markus Fehrenz
10
--! @date   2011/12/05
11
--!
12
--! @details
13
--! The AXI std_logic_vector input is mapped to an internal information type.
14
--! Further the correct output order is handled.
15
--!
16
 
17
library ieee;
18
use ieee.std_logic_1164.all;
19
use ieee.numeric_std.all;
20
 
21
library dec_viterbi;
22
use dec_viterbi.pkg_param.all;
23
use dec_viterbi.pkg_param_derived.all;
24
use dec_viterbi.pkg_types.all;
25
use dec_viterbi.pkg_components.all;
26
use dec_viterbi.pkg_trellis.all;
27
 
28
 
29
entity dec_viterbi is
30
        port(
31
 
32
        --
33
        -- The core only uses AXI4-Stream interfaces,
34
        -- based on AMBA4 AXI4-Stream Protocol with restrictions according to
35
        -- Xilinx Migration, described in Xilinx AXI Reference UG761 (v13.3).
36
        --
37
 
38
        aclk      : in std_logic;
39
 
40
        -- Synchronous reset, active low.
41
        aresetn   : in std_logic;
42
 
43
 
44
        --
45
        -- Slave (input) data signals
46
        -- Delivers the parity LLR values, one byte per LLR value.
47
        --
48
        s_axis_input_tvalid : in std_logic;
49
        s_axis_input_tdata  : in std_logic_vector(31 downto 0);
50
        s_axis_input_tlast  : in std_logic;
51
        s_axis_input_tready : out std_logic;
52
 
53
 
54
        --
55
        -- Master (output) data signals
56
        -- Delivers the decoded systematic (payload) bits.
57
        --
58
        m_axis_output_tvalid : out std_logic;
59
        m_axis_output_tdata  : out std_logic;
60
        m_axis_output_tlast  : out std_logic;
61
        m_axis_output_tready : in  std_logic;
62
 
63
 
64
        --
65
        -- Slave (input) configuration signals
66
        -- Configures window length and acquisition length.
67
        --
68
        s_axis_ctrl_tvalid : in std_logic;
69
        s_axis_ctrl_tdata  : in std_logic_vector(31 downto 0);
70
        s_axis_ctrl_tlast  : in std_logic;
71
        s_axis_ctrl_tready : out std_logic
72
);
73
end entity dec_viterbi;
74
 
75
 
76
architecture rtl of dec_viterbi is
77
 
78
        alias clk is aclk;
79
        signal rst : std_logic;
80
 
81
        -- split tdata into input array
82
        signal input : t_input_block;
83
 
84
        -- branch signals
85
        signal branch_tvalid  : std_logic_vector(NUMBER_BRANCH_UNITS - 1 downto 0);
86
        signal branch_tdata   : t_branch;
87
        signal branch_tlast   : std_logic_vector(NUMBER_BRANCH_UNITS - 1 downto 0);
88
        signal branch_tready  : std_logic_vector(NUMBER_BRANCH_UNITS - 1 downto 0);
89
 
90
        -- acs signals
91
        signal acs_tvalid     : std_logic_vector(NUMBER_TRELLIS_STATES - 1 downto 0);
92
        signal acs_tlast      : std_logic_vector(NUMBER_TRELLIS_STATES - 1 downto 0);
93
        signal acs_tready     : std_logic_vector(NUMBER_TRELLIS_STATES - 1 downto 0);
94
        signal acs_dec_tdata  : std_logic_vector(NUMBER_TRELLIS_STATES - 1 downto 0);
95
        signal acs_prob_tdata : t_node;
96
 
97
        -- ram signals
98
        signal ram_tready                             : std_logic;
99
        signal ram_tvalid, ram_tlast, ram_window_tuser, ram_last_tuser : std_logic_vector(1 downto 0);
100
        signal ram_tdata                                               : t_ram_rd_data;
101
 
102
        -- traceback signals
103
        signal traceback_tvalid, traceback_tdata : std_logic_vector(1 downto 0);
104
        signal traceback_tready, traceback_tlast : std_logic_vector(1 downto 0);
105
        signal traceback_last_tuser              : std_logic_vector(1 downto 0);
106
 
107
        -- reorder signals
108
        signal reorder_tready, reorder_tvalid : std_logic_vector(1 downto 0);
109
        signal reorder_tdata, reorder_tlast   : std_logic_vector(1 downto 0);
110
        signal reorder_last_tuser             : std_logic_vector(1 downto 0);
111
        signal reorder_recursion_tvalid       : std_logic;
112
        signal reorder_recursion_tdata        : std_logic;
113
        signal reorder_recursion_tlast        : std_logic;
114
 
115
        -- recursion signals
116
        signal recursion_tready         : std_logic;
117
 
118
        -- output signals
119
        signal output_tready : std_logic_vector(1 downto 0);
120
        signal current_active, semaphore_output : integer range 1 downto 0;
121
 
122
begin
123
 
124
        --
125
        -- There is always one byte of data for each LLR value, even though each
126
        -- LLR value is represented with BW_LLR_INPUT bits. Hence, only
127
        -- BW_LLR_INPUT bits are extracted from the byte.
128
        --
129
        gen_input_assignment: for i in NUMBER_PARITY_BITS - 1 downto 0 generate
130
        begin
131
                input(i) <= signed(s_axis_input_tdata(8 * i + BW_LLR_INPUT - 1 downto 8 * i));
132
        end generate gen_input_assignment;
133
 
134
        rst <= not aresetn;
135
 
136
        ------------------------------
137
        --- Portmapping components ---
138
        ------------------------------
139
 
140
        -------------------------------------
141
        -- Branch metric unit
142
        --------------------------------------
143
 
144
        gen_branch_distance : for i in NUMBER_BRANCH_UNITS - 1 downto 0 generate
145
        begin
146
                inst_branch_distance : branch_distance
147
                generic map(
148
                        EDGE_WEIGHT => std_logic_vector(to_unsigned(i, NUMBER_PARITY_BITS))
149
                )
150
                port map(
151
                        clk => clk,
152
                        rst => rst,
153
 
154
                        s_axis_input_tvalid  => s_axis_input_tvalid,
155
                        s_axis_input_tdata   => input,
156
                        s_axis_input_tlast   => s_axis_input_tlast,
157
                        s_axis_input_tready  => branch_tready(i),
158
 
159
                        m_axis_output_tvalid => branch_tvalid(i),
160
                        m_axis_output_tdata  => branch_tdata(i),
161
                        m_axis_output_tlast  => branch_tlast(i),
162
                        m_axis_output_tready => acs_tready(0)
163
                );
164
        end generate gen_branch_distance;
165
 
166
 
167
        -------------------------------------
168
        -- ACS unit (path metric calculation)
169
        --------------------------------------
170
 
171
        gen_acs : for i in 0 to NUMBER_TRELLIS_STATES - 1 generate
172
                signal inbranch_tdata_low  : std_logic_vector(BW_BRANCH_RESULT - 1 downto 0);
173
                signal inbranch_tdata_high : std_logic_vector(BW_BRANCH_RESULT - 1 downto 0);
174
                signal inprev_tdata_low  : std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
175
                signal inprev_tdata_high : std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
176
        begin
177
                inbranch_tdata_low  <= branch_tdata(to_integer(unsigned(TRANSITIONS(i)(0))));
178
                inbranch_tdata_high <= branch_tdata(to_integer(unsigned(TRANSITIONS(i)(1))));
179
                inprev_tdata_low    <= acs_prob_tdata(to_integer(unsigned(PREVIOUS_STATES(i)(0))));
180
                inprev_tdata_high   <= acs_prob_tdata(to_integer(unsigned(PREVIOUS_STATES(i)(1))));
181
 
182
                inst_acs : acs
183
                generic map(
184
                        initialize_value => INITIALIZE_TRELLIS(i)
185
                )
186
                port map(
187
                        clk => clk,
188
                        rst => rst,
189
 
190
                        s_axis_inbranch_tvalid     => branch_tvalid(0),
191
                        s_axis_inbranch_tdata_low  => inbranch_tdata_low,
192
                        s_axis_inbranch_tdata_high => inbranch_tdata_high,
193
                        s_axis_inbranch_tlast      => branch_tlast(0),
194
                        s_axis_inbranch_tready     => acs_tready(i),
195
 
196
                        s_axis_inprev_tvalid     => '1',
197
                        s_axis_inprev_tdata_low  => inprev_tdata_low,
198
                        s_axis_inprev_tdata_high => inprev_tdata_high,
199
                        s_axis_inprev_tready     => open,
200
 
201
                        m_axis_outprob_tvalid  => open,
202
                        m_axis_outprob_tdata   => acs_prob_tdata(i),
203
                        m_axis_outprob_tready  => '1',
204
 
205
                        m_axis_outdec_tvalid   => acs_tvalid(i),
206
                        m_axis_outdec_tdata    => acs_dec_tdata(i),
207
                        m_axis_outdec_tlast    => acs_tlast(i),
208
                        m_axis_outdec_tready   => ram_tready
209
                );
210
        end generate gen_acs;
211
 
212
 
213
        -------------------------------
214
        -- Traceback
215
        -------------------------------
216
 
217
        inst_ram_ctrl : ram_ctrl
218
        port map (
219
                clk => clk,
220
                rst => rst,
221
 
222
                s_axis_input_tvalid => acs_tvalid(0),
223
                s_axis_input_tdata  => acs_dec_tdata,
224
                s_axis_input_tlast  => acs_tlast(0),
225
                s_axis_input_tready => ram_tready,
226
 
227
                m_axis_output_tvalid       => ram_tvalid,
228
                m_axis_output_tdata        => ram_tdata,
229
                m_axis_output_tlast        => ram_tlast,
230
                m_axis_output_tready       => traceback_tready,
231
                m_axis_output_window_tuser => ram_window_tuser,
232
                m_axis_output_last_tuser   => ram_last_tuser,
233
 
234
                s_axis_ctrl_tvalid => s_axis_ctrl_tvalid,
235
                s_axis_ctrl_tdata  => s_axis_ctrl_tdata,
236
                s_axis_ctrl_tready => s_axis_ctrl_tready
237
        );
238
 
239
 
240
        gen_inst_trellis_traceback : for i in 1 downto 0 generate
241
        begin
242
                inst_trellis_traceback : trellis_traceback
243
                port map(
244
                        clk => clk,
245
                        rst => rst,
246
 
247
                        s_axis_input_tvalid       => ram_tvalid(i),
248
                        s_axis_input_tdata        => ram_tdata(i),
249
                        s_axis_input_tlast        => ram_tlast(i),
250
                        s_axis_input_tready       => traceback_tready(i),
251
                        s_axis_input_window_tuser => ram_window_tuser(i),
252
                        s_axis_input_last_tuser   => ram_last_tuser(i),
253
 
254
                        m_axis_output_tvalid     => traceback_tvalid(i),
255
                        m_axis_output_tdata      => traceback_tdata(i),
256
                        m_axis_output_tlast      => traceback_tlast(i),
257
                        m_axis_output_last_tuser => traceback_last_tuser(i),
258
                        m_axis_output_tready     => reorder_tready(i)
259
                );
260
        end generate gen_inst_trellis_traceback;
261
 
262
 
263
        -------------------------------
264
        -- Reverse output order
265
        -------------------------------
266
 
267
        gen_inst_reorder : for i in 1 downto 0 generate
268
        begin
269
                inst_reorder : reorder
270
                port map(
271
                        clk => clk,
272
                        rst => rst,
273
 
274
                        s_axis_input_tvalid     => traceback_tvalid(i),
275
                        s_axis_input_tdata      => traceback_tdata(i),
276
                        s_axis_input_tlast      => traceback_tlast(i),
277
                        s_axis_input_last_tuser => traceback_last_tuser(i),
278
                        s_axis_input_tready     => reorder_tready(i),
279
 
280
                        m_axis_output_tvalid     => reorder_tvalid(i),
281
                        m_axis_output_tdata      => reorder_tdata(i),
282
                        m_axis_output_tlast      => reorder_tlast(i),
283
                        m_axis_output_last_tuser => reorder_last_tuser(i),
284
                        m_axis_output_tready     => output_tready(i)
285
                );
286
        end generate gen_inst_reorder;
287
 
288
 
289
        ------------------------------
290
        -- Recursive codes handling --
291
        ------------------------------
292
 
293
        gen_inst_recursion : if FEEDBACK_POLYNOMIAL /= 0 generate
294
        begin
295
                inst_recursion : recursion
296
                port map(
297
                        clk => clk,
298
                        rst => rst,
299
 
300
                        s_axis_input_tvalid     => reorder_recursion_tvalid,
301
                        s_axis_input_tdata      => reorder_recursion_tdata,
302
                        s_axis_input_tlast      => reorder_recursion_tlast,
303
                        s_axis_input_tready     => recursion_tready,
304
 
305
                        m_axis_output_tvalid     => m_axis_output_tvalid,
306
                        m_axis_output_tdata      => m_axis_output_tdata,
307
                        m_axis_output_tlast      => m_axis_output_tlast,
308
                        m_axis_output_tready     => m_axis_output_tready
309
                );
310
        end generate gen_inst_recursion;
311
 
312
        -------------------------------
313
        -- Input interface handling
314
        -------------------------------
315
 
316
        s_axis_input_tready <= branch_tready(0);
317
 
318
 
319
        -------------------------------
320
        -- Output interface handling
321
        -------------------------------
322
 
323
        no_recursion: if FEEDBACK_POLYNOMIAL = 0 generate
324
                m_axis_output_tdata  <= reorder_tdata(0) when reorder_tvalid(0) = '1' else
325
                                        reorder_tdata(1);
326
 
327
                m_axis_output_tvalid <= '1' when reorder_tvalid(0) = '1' or reorder_tvalid(1) = '1' else
328
                                        '0';
329
 
330
                m_axis_output_tlast  <= '1' when reorder_tlast(0) = '1' or reorder_tlast(1) = '1' else
331
                                        '0';
332
 
333
                output_tready(0) <= '1' when (semaphore_output = 1 or current_active = 0) and m_axis_output_tready = '1' else
334
                                    '0';
335
                output_tready(1) <= '1' when (semaphore_output = 1 or current_active = 1) and m_axis_output_tready = '1' else
336
                                    '0';
337
        end generate no_recursion;
338
 
339
 
340
        recursion : if FEEDBACK_POLYNOMIAL /= 0 generate
341
        begin
342
                reorder_recursion_tvalid <= '1' when reorder_tvalid(0) = '1' or reorder_tvalid(1) = '1' else
343
                                            '0';
344
 
345
                reorder_recursion_tdata  <= reorder_tdata(0) when reorder_tvalid(0) = '1' else
346
                                            reorder_tdata(1);
347
 
348
                reorder_recursion_tlast   <= '1' when reorder_tlast(0) = '1' or reorder_tlast(1) = '1' else
349
                                            '0';
350
 
351
                output_tready(0) <= '1' when (semaphore_output = 1 or current_active = 0) and recursion_tready = '1' else
352
                                    '0';
353
                output_tready(1) <= '1' when (semaphore_output = 1 or current_active = 1) and recursion_tready = '1' else
354
                                    '0';
355
        end generate recursion;
356
 
357
 
358
        -- Check and merge reordering outputs and block if necessary.
359
        pr_reorder_tready : process(clk) is
360
        begin
361
        if rising_edge(clk) then
362
                if rst = '1' then
363
                        current_active <= 0;
364
                        semaphore_output <= 1;
365
                else
366
                        if reorder_last_tuser(current_active) = '1' then
367
                                semaphore_output <= 1;
368
                        end if;
369
                        if semaphore_output = 1 then
370
                                if reorder_tvalid(0) = '1' then
371
                                        current_active <= 0;
372
                                        semaphore_output <= 0;
373
                                end if;
374
                                if reorder_tvalid(1) = '1' then
375
                                        current_active <= 1;
376
                                        semaphore_output <= 0;
377
                                end if;
378
                        end if;
379
                end if;
380
        end if;
381
        end process pr_reorder_tready;
382
 
383
end architecture rtl;

powered by: WebSVN 2.1.0

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