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 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  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 6 mfehrenz
        -- buffer signals
85
        signal buffer_tdata  : std_logic_vector(31 downto 0);
86
        signal buffer_tvalid : std_logic;
87
        signal buffer_tlast  : std_logic;
88
 
89 2 mfehrenz
        -- branch signals
90
        signal branch_tvalid  : std_logic_vector(NUMBER_BRANCH_UNITS - 1 downto 0);
91
        signal branch_tdata   : t_branch;
92
        signal branch_tlast   : std_logic_vector(NUMBER_BRANCH_UNITS - 1 downto 0);
93
        signal branch_tready  : std_logic_vector(NUMBER_BRANCH_UNITS - 1 downto 0);
94
 
95
        -- acs signals
96
        signal acs_tvalid     : std_logic_vector(NUMBER_TRELLIS_STATES - 1 downto 0);
97
        signal acs_tlast      : std_logic_vector(NUMBER_TRELLIS_STATES - 1 downto 0);
98
        signal acs_tready     : std_logic_vector(NUMBER_TRELLIS_STATES - 1 downto 0);
99
        signal acs_dec_tdata  : std_logic_vector(NUMBER_TRELLIS_STATES - 1 downto 0);
100
        signal acs_prob_tdata : t_node;
101
 
102
        -- ram signals
103
        signal ram_tready                             : std_logic;
104
        signal ram_tvalid, ram_tlast, ram_window_tuser, ram_last_tuser : std_logic_vector(1 downto 0);
105
        signal ram_tdata                                               : t_ram_rd_data;
106
 
107
        -- traceback signals
108
        signal traceback_tvalid, traceback_tdata : std_logic_vector(1 downto 0);
109
        signal traceback_tready, traceback_tlast : std_logic_vector(1 downto 0);
110
        signal traceback_last_tuser              : std_logic_vector(1 downto 0);
111
 
112
        -- reorder signals
113
        signal reorder_tready, reorder_tvalid : std_logic_vector(1 downto 0);
114
        signal reorder_tdata, reorder_tlast   : std_logic_vector(1 downto 0);
115
        signal reorder_last_tuser             : std_logic_vector(1 downto 0);
116
 
117
        -- output signals
118
        signal output_tready : std_logic_vector(1 downto 0);
119 6 mfehrenz
        signal current_active : integer range 1 downto 0;
120 2 mfehrenz
 
121
begin
122
 
123
        --
124
        -- There is always one byte of data for each LLR value, even though each
125
        -- LLR value is represented with BW_LLR_INPUT bits. Hence, only
126
        -- BW_LLR_INPUT bits are extracted from the byte.
127
        --
128
        gen_input_assignment: for i in NUMBER_PARITY_BITS - 1 downto 0 generate
129
        begin
130 6 mfehrenz
                input(i) <= signed(buffer_tdata(8 * i + BW_LLR_INPUT - 1 downto 8 * i));
131 2 mfehrenz
        end generate gen_input_assignment;
132
 
133
        rst <= not aresetn;
134
 
135
        ------------------------------
136
        --- Portmapping components ---
137
        ------------------------------
138
 
139
        -------------------------------------
140 6 mfehrenz
        -- AXI4S input buffer
141
        --------------------------------------
142
 
143
        inst_axi4s_buffer: axi4s_buffer
144
        generic map(
145
                DATA_WIDTH => 32
146
        )
147
        port map(
148
                clk => clk,
149
                rst => rst,
150
 
151
                input        => s_axis_input_tdata,
152
                input_valid  => s_axis_input_tvalid,
153
                input_last   => s_axis_input_tlast,
154
                input_accept => s_axis_input_tready,
155
 
156
                output        => buffer_tdata,
157
                output_valid  => buffer_tvalid,
158
                output_last   => buffer_tlast,
159
                output_accept => branch_tready(0)
160
        );
161
 
162
        -------------------------------------
163 2 mfehrenz
        -- Branch metric unit
164
        --------------------------------------
165
 
166
        gen_branch_distance : for i in NUMBER_BRANCH_UNITS - 1 downto 0 generate
167
        begin
168
                inst_branch_distance : branch_distance
169
                generic map(
170
                        EDGE_WEIGHT => std_logic_vector(to_unsigned(i, NUMBER_PARITY_BITS))
171
                )
172
                port map(
173
                        clk => clk,
174
                        rst => rst,
175
 
176 6 mfehrenz
                        s_axis_input_tvalid  => buffer_tvalid,
177 2 mfehrenz
                        s_axis_input_tdata   => input,
178 6 mfehrenz
                        s_axis_input_tlast   => buffer_tlast,
179 2 mfehrenz
                        s_axis_input_tready  => branch_tready(i),
180
 
181
                        m_axis_output_tvalid => branch_tvalid(i),
182
                        m_axis_output_tdata  => branch_tdata(i),
183
                        m_axis_output_tlast  => branch_tlast(i),
184
                        m_axis_output_tready => acs_tready(0)
185
                );
186
        end generate gen_branch_distance;
187
 
188
 
189
        -------------------------------------
190
        -- ACS unit (path metric calculation)
191
        --------------------------------------
192
 
193
        gen_acs : for i in 0 to NUMBER_TRELLIS_STATES - 1 generate
194
                signal inbranch_tdata_low  : std_logic_vector(BW_BRANCH_RESULT - 1 downto 0);
195
                signal inbranch_tdata_high : std_logic_vector(BW_BRANCH_RESULT - 1 downto 0);
196
                signal inprev_tdata_low  : std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
197
                signal inprev_tdata_high : std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0);
198
        begin
199
                inbranch_tdata_low  <= branch_tdata(to_integer(unsigned(TRANSITIONS(i)(0))));
200
                inbranch_tdata_high <= branch_tdata(to_integer(unsigned(TRANSITIONS(i)(1))));
201
                inprev_tdata_low    <= acs_prob_tdata(to_integer(unsigned(PREVIOUS_STATES(i)(0))));
202
                inprev_tdata_high   <= acs_prob_tdata(to_integer(unsigned(PREVIOUS_STATES(i)(1))));
203
 
204
                inst_acs : acs
205
                generic map(
206
                        initialize_value => INITIALIZE_TRELLIS(i)
207
                )
208
                port map(
209
                        clk => clk,
210
                        rst => rst,
211
 
212
                        s_axis_inbranch_tvalid     => branch_tvalid(0),
213
                        s_axis_inbranch_tdata_low  => inbranch_tdata_low,
214
                        s_axis_inbranch_tdata_high => inbranch_tdata_high,
215
                        s_axis_inbranch_tlast      => branch_tlast(0),
216
                        s_axis_inbranch_tready     => acs_tready(i),
217
 
218
                        s_axis_inprev_tvalid     => '1',
219
                        s_axis_inprev_tdata_low  => inprev_tdata_low,
220
                        s_axis_inprev_tdata_high => inprev_tdata_high,
221
                        s_axis_inprev_tready     => open,
222
 
223
                        m_axis_outprob_tvalid  => open,
224
                        m_axis_outprob_tdata   => acs_prob_tdata(i),
225
                        m_axis_outprob_tready  => '1',
226
 
227
                        m_axis_outdec_tvalid   => acs_tvalid(i),
228
                        m_axis_outdec_tdata    => acs_dec_tdata(i),
229
                        m_axis_outdec_tlast    => acs_tlast(i),
230
                        m_axis_outdec_tready   => ram_tready
231
                );
232
        end generate gen_acs;
233
 
234
 
235
        -------------------------------
236
        -- Traceback
237
        -------------------------------
238
 
239
        inst_ram_ctrl : ram_ctrl
240
        port map (
241
                clk => clk,
242
                rst => rst,
243
 
244
                s_axis_input_tvalid => acs_tvalid(0),
245
                s_axis_input_tdata  => acs_dec_tdata,
246
                s_axis_input_tlast  => acs_tlast(0),
247
                s_axis_input_tready => ram_tready,
248
 
249
                m_axis_output_tvalid       => ram_tvalid,
250
                m_axis_output_tdata        => ram_tdata,
251
                m_axis_output_tlast        => ram_tlast,
252
                m_axis_output_tready       => traceback_tready,
253
                m_axis_output_window_tuser => ram_window_tuser,
254
                m_axis_output_last_tuser   => ram_last_tuser,
255
 
256
                s_axis_ctrl_tvalid => s_axis_ctrl_tvalid,
257
                s_axis_ctrl_tdata  => s_axis_ctrl_tdata,
258
                s_axis_ctrl_tready => s_axis_ctrl_tready
259
        );
260
 
261
 
262
        gen_inst_trellis_traceback : for i in 1 downto 0 generate
263
        begin
264
                inst_trellis_traceback : trellis_traceback
265
                port map(
266
                        clk => clk,
267
                        rst => rst,
268
 
269
                        s_axis_input_tvalid       => ram_tvalid(i),
270
                        s_axis_input_tdata        => ram_tdata(i),
271
                        s_axis_input_tlast        => ram_tlast(i),
272
                        s_axis_input_tready       => traceback_tready(i),
273
                        s_axis_input_window_tuser => ram_window_tuser(i),
274
                        s_axis_input_last_tuser   => ram_last_tuser(i),
275
 
276
                        m_axis_output_tvalid     => traceback_tvalid(i),
277
                        m_axis_output_tdata      => traceback_tdata(i),
278
                        m_axis_output_tlast      => traceback_tlast(i),
279
                        m_axis_output_last_tuser => traceback_last_tuser(i),
280
                        m_axis_output_tready     => reorder_tready(i)
281
                );
282
        end generate gen_inst_trellis_traceback;
283
 
284
 
285
        -------------------------------
286
        -- Reverse output order
287
        -------------------------------
288
 
289
        gen_inst_reorder : for i in 1 downto 0 generate
290
        begin
291
                inst_reorder : reorder
292
                port map(
293
                        clk => clk,
294
                        rst => rst,
295
 
296
                        s_axis_input_tvalid     => traceback_tvalid(i),
297
                        s_axis_input_tdata      => traceback_tdata(i),
298
                        s_axis_input_tlast      => traceback_tlast(i),
299
                        s_axis_input_last_tuser => traceback_last_tuser(i),
300
                        s_axis_input_tready     => reorder_tready(i),
301
 
302
                        m_axis_output_tvalid     => reorder_tvalid(i),
303
                        m_axis_output_tdata      => reorder_tdata(i),
304
                        m_axis_output_tlast      => reorder_tlast(i),
305
                        m_axis_output_last_tuser => reorder_last_tuser(i),
306
                        m_axis_output_tready     => output_tready(i)
307
                );
308
        end generate gen_inst_reorder;
309
 
310
 
311
        ------------------------------
312
        -- Recursive codes handling --
313
        ------------------------------
314
 
315
        gen_inst_recursion : if FEEDBACK_POLYNOMIAL /= 0 generate
316 6 mfehrenz
                signal reorder_recursion_tvalid : std_logic;
317
                signal reorder_recursion_tdata  : std_logic;
318
                signal reorder_recursion_tlast  : std_logic;
319
                signal recursion_tready         : std_logic;
320 2 mfehrenz
        begin
321
                inst_recursion : recursion
322
                port map(
323
                        clk => clk,
324
                        rst => rst,
325
 
326
                        s_axis_input_tvalid     => reorder_recursion_tvalid,
327
                        s_axis_input_tdata      => reorder_recursion_tdata,
328
                        s_axis_input_tlast      => reorder_recursion_tlast,
329
                        s_axis_input_tready     => recursion_tready,
330
 
331
                        m_axis_output_tvalid     => m_axis_output_tvalid,
332
                        m_axis_output_tdata      => m_axis_output_tdata,
333
                        m_axis_output_tlast      => m_axis_output_tlast,
334
                        m_axis_output_tready     => m_axis_output_tready
335
                );
336 6 mfehrenz
 
337
                -------------------------------
338
                -- Output interface handling
339
                -------------------------------
340
 
341
                reorder_recursion_tvalid <= '1' when reorder_tvalid(0) = '1' or reorder_tvalid(1) = '1' else
342
                                            '0';
343
 
344
                reorder_recursion_tdata  <= reorder_tdata(0) when current_active = 0 else
345
                                            reorder_tdata(1);
346
 
347
                reorder_recursion_tlast   <= '1' when reorder_tlast(0) = '1' or reorder_tlast(1) = '1' else
348
                                            '0';
349
 
350
                output_tready(0) <= '1' when (current_active = 0) and m_axis_output_tready = '1' else
351
                                    '0';
352
                output_tready(1) <= '1' when (current_active = 1) and m_axis_output_tready = '1' else
353
                                    '0';
354 2 mfehrenz
        end generate gen_inst_recursion;
355
 
356
 
357
 
358 6 mfehrenz
        no_recursion: if FEEDBACK_POLYNOMIAL = 0 generate
359 2 mfehrenz
 
360 6 mfehrenz
                -------------------------------
361
                -- Output interface handling
362
                -------------------------------
363 2 mfehrenz
 
364 6 mfehrenz
                m_axis_output_tdata  <= reorder_tdata(0) when current_active = 0 else
365 2 mfehrenz
                                        reorder_tdata(1);
366
 
367
                m_axis_output_tvalid <= '1' when reorder_tvalid(0) = '1' or reorder_tvalid(1) = '1' else
368
                                        '0';
369
 
370
                m_axis_output_tlast  <= '1' when reorder_tlast(0) = '1' or reorder_tlast(1) = '1' else
371
                                        '0';
372
 
373 6 mfehrenz
                output_tready(0) <= '1' when (current_active = 0) and m_axis_output_tready = '1' else
374 2 mfehrenz
                                    '0';
375 6 mfehrenz
                output_tready(1) <= '1' when (current_active = 1) and m_axis_output_tready = '1' else
376 2 mfehrenz
                                    '0';
377
        end generate no_recursion;
378
 
379
 
380
        recursion : if FEEDBACK_POLYNOMIAL /= 0 generate
381
        begin
382
        end generate recursion;
383
 
384
 
385
        -- Check and merge reordering outputs and block if necessary.
386
        pr_reorder_tready : process(clk) is
387
        begin
388
        if rising_edge(clk) then
389
                if rst = '1' then
390
                        current_active <= 0;
391
                else
392 6 mfehrenz
                        if reorder_tvalid(current_active) = '1' and m_axis_output_tready = '1' and reorder_last_tuser(current_active) = '1' then
393
                                current_active <= 1 - current_active;
394 2 mfehrenz
                        end if;
395
                end if;
396
        end if;
397
        end process pr_reorder_tready;
398
 
399
end architecture rtl;

powered by: WebSVN 2.1.0

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