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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.accelerator/] [dct_to_hibi/] [1.0/] [hdl/] [dct_to_hibi_v2.vhd.bak] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : DCT to Hibi. Connects dctQidct block to HIBI Wrapper
3
-- Project    :
4
-------------------------------------------------------------------------------
5
-- File       : dct_to_hibi_v2.vhd
6
-- Author     : rasmusa
7
-- Created    : 01.07.2006
8
-- Last update: 2006-08-22
9
--
10
-- Input:
11
-- 1. Two address to send the results to (one for quant, one for idct)
12
-- 2. Control word for the current macroblock
13
--    Control word structure: bit 6: chroma(1)/luma(0), 5: intra(1)/inter(0),
14
--                             4..0: quantizer parameter (QP)
15
-- 3. Then the DCT data ( 8x8x6 x 16-bit values = 384 x 16 bit )
16
--
17
-- Chroma/luma: 4 luma, 2 chroma
18
--
19
-- Outputs:
20
-- Outputs are 16-bit words which are packed up to hibi. If hibi width is
21
-- 32b, then 2 16-bit words are combined into one hibi word.
22
-- 01. quant results: 1. 8*8 x 16bit values to quant result address
23
-- 02. idct  results: 1. 8*8 x 16bit values to idct  result address
24
-- 03. quant results: 2. 8*8 x 16bit values to quant result address
25
-- 04. idct  results: 2. 8*8 x 16bit values to idct  result address
26
-- 05. quant results: 3. 8*8 x 16bit values to quant result address
27
-- 06. idct  results: 3. 8*8 x 16bit values to idct  result address
28
-- 07. quant results: 4. 8*8 x 16bit values to quant result address
29
-- 08. idct  results: 4. 8*8 x 16bit values to idct  result address
30
-- 09. quant results: 5. 8*8 x 16bit values to quant result address
31
-- 10. idct  results: 5. 8*8 x 16bit values to idct  result address
32
-- 11. quant results: 6. 8*8 x 16bit values to quant result address
33
-- 12. quant results: 1 word with bits 5..0 determing if 8x8 quant blocks(1-6)
34
--                    has all values zeros (except dc-component in intra)
35
-- 13. idct  results: 6. 8*8 x 16bit values to idct  result address
36
-------------------------------------------------------------------------------
37
-- Total amount of 16-bit values is: 384 per result address + 1 hibi word to
38
-- quantization result address.
39
--
40
-- With default parameter:
41
-- Total of 193 words of data to quant address (if data_width_g = 32)
42
-- Total of 192 words of data to idct address (if data_width_g = 32)
43
-------------------------------------------------------------------------------
44
-- Copyright (c) 2005
45
-------------------------------------------------------------------------------
46
-- Revisions  :
47
-- Date        Version  Author  Description
48
-- 01.07.2005  1.0      AK      Created
49
-- 11.08.2005  1.1      AK      all-zero quant result given
50
-- 16.05.2005  1.11     AK      chroma/luma bit
51
-- 17.07.2007  1.12i    AR      Major rewrite, IF changed to R4, ...
52
-------------------------------------------------------------------------------
53
 
54
library ieee;
55
use ieee.std_logic_1164.all;
56
use ieee.numeric_std.all;
57
use ieee.std_logic_misc.all;
58
 
59
-- For or_reduce
60
use ieee.std_logic_misc.all;
61
 
62
entity dct_to_hibi is
63
  generic (
64
    data_width_g   : integer := 32;
65
    comm_width_g   : integer := 3;
66
    dct_width_g    : integer;           -- Incoming data width(9b)
67
    quant_width_g  : integer;           -- Quantizated data width(8b)
68
    idct_width_g   : integer;           -- Data width after IDCT(9b)
69
    use_self_rel_g : integer;           -- Does it release itself from RTM?
70
    own_address_g  : integer;           -- Used for self-release
71
    rtm_address_g  : integer;           -- Used for self-release
72
    debug_w_g      : integer := 1
73
    );
74
 
75
  port (
76
    clk   : in std_logic;
77
    rst_n : in std_logic;
78
 
79
    -- HIBI signals
80
    hibi_av_out   : out std_logic;
81
    hibi_data_out : out std_logic_vector (data_width_g-1 downto 0);
82
    hibi_comm_out : out std_logic_vector (comm_width_g-1 downto 0);
83
    hibi_we_out   : out std_logic;
84
    hibi_full_in  : in  std_logic;
85
 
86
    hibi_re_out   : out std_logic;
87
    hibi_av_in    : in  std_logic;
88
    hibi_data_in  : in  std_logic_vector (data_width_g-1 downto 0);
89
    hibi_comm_in  : in  std_logic_vector (comm_width_g-1 downto 0);
90
    hibi_empty_in : in  std_logic;
91
 
92
    -- DCT signals
93
    wr_dct_out          : out std_logic;
94
    quant_ready4col_out : out std_logic;
95
    idct_ready4col_out  : out std_logic;
96
    data_dct_out        : out std_logic_vector(dct_width_g-1 downto 0);
97
    intra_out           : out std_logic;
98
    loadQP_out          : out std_logic;
99
    QP_out              : out std_logic_vector (4 downto 0);
100
    chroma_out          : out std_logic;
101
 
102
    data_idct_in     : in  std_logic_vector(idct_width_g-1 downto 0);
103
    data_quant_in    : in  std_logic_vector(quant_width_g-1 downto 0);
104
    dct_ready4col_in : in  std_logic;
105
    wr_idct_in       : in  std_logic;
106
    wr_quant_in      : in  std_logic;
107
    debug_out        : out std_logic_vector(debug_w_g-1 downto 0)
108
 
109
    );
110
 
111
end dct_to_hibi;
112
 
113
architecture rtl of dct_to_hibi is
114
 
115
  -- How many 8x8 blocks are sent after a request
116
  -- (4 x luma + 2 x chroma = a 16x16 macroblock )
117
  constant n_blocks_per_req_c : integer := 6;
118
 
119
  -- Incoming value width
120
  constant dct_word_width_in_bus_c : integer := 16;
121
 
122
  -- Result value width
123
  constant output_word_width_c : integer := 16;
124
 
125
  constant rx_elements_c : integer := 8*8*n_blocks_per_req_c;
126
 
127
  -- How many 16-bit values in a hibi word
128
  constant tx_fifo_value_sel_max_c : integer := data_width_g/output_word_width_c;
129
 
130
  -- Because dctQidct pushes out 8 values at a time, fifo must be:
131
  constant tx_fifo_depth_c : integer := 8/tx_fifo_value_sel_max_c;
132
 
133
  -- /tx_fifo_value_sel_max_c because multiple values in a word
134
  constant n_values_in_block_c : integer := 8*8/tx_fifo_value_sel_max_c;
135
 
136
  -- Input data (received from the dct's point of view )
137
  signal rx_counter_r : integer range 0 to rx_elements_c-1;
138
 
139
  -- tx from the dct's point of view ( actually results )
140
  -- Signals for quant result fifo
141
  signal tx_q_fifo_full        : std_logic;
142
  signal tx_q_fifo_empty       : std_logic;
143
  signal tx_q_fifo_re          : std_logic;
144
  signal tx_q_fifo_we          : std_logic;
145
  signal tx_q_fifo_data_from   : std_logic_vector(data_width_g-1 downto 0);
146
  signal tx_q_fifo_data_to_r   : std_logic_vector(data_width_g-1 downto 0);
147
  signal tx_q_fifo_value_sel_r : integer range 0 to tx_fifo_value_sel_max_c-1;
148
 
149
  -- Signals for idct result fifo
150
  signal tx_i_fifo_full        : std_logic;
151
  signal tx_i_fifo_empty       : std_logic;
152
  signal tx_i_fifo_re          : std_logic;
153
  signal tx_i_fifo_we          : std_logic;
154
  signal tx_i_fifo_data_from   : std_logic_vector(data_width_g-1 downto 0);
155
  signal tx_i_fifo_data_to_r   : std_logic_vector(data_width_g-1 downto 0);
156
  signal tx_i_fifo_value_sel_r : integer range 0 to tx_fifo_value_sel_max_c-1;
157
 
158
  -- Signals for tx fifo (muxed to either to q or i fifo)
159
  signal tx_fifo_full      : std_logic;
160
  signal tx_fifo_empty     : std_logic;
161
  signal tx_fifo_re        : std_logic;
162
  signal tx_fifo_re_r      : std_logic;
163
  signal tx_fifo_data_from : std_logic_vector(data_width_g-1 downto 0);
164
  signal tx_data_counter_r : integer range 0 to n_values_in_block_c-1;
165
 
166
  -- n_blocks_per_req_c result blocks of a kind (quant and idct). Sum is 2*n_blocks_per_req_c
167
  constant result_block_count_c   : integer := n_blocks_per_req_c*2;
168
  signal   result_block_counter_r : integer range 0 to result_block_count_c-1;
169
 
170
  component fifo
171
    generic (
172
      data_width_g : integer;
173
      depth_g      : integer);
174
    port (
175
      clk       : in  std_logic;
176
      rst_n     : in  std_logic;
177
      data_in   : in  std_logic_vector (data_width_g-1 downto 0);
178
      we_in     : in  std_logic;
179
      one_p_out : out std_logic;
180
      full_out  : out std_logic;
181
      data_out  : out std_logic_vector (data_width_g-1 downto 0);
182
      re_in     : in  std_logic;
183
      empty_out : out std_logic;
184
      one_d_out : out std_logic);
185
  end component;
186
 
187
 
188
  -- Originally Ari's counter which tells if current block is luma or chroma.
189
  component cl_cnt
190
    generic (
191
      n_luma_g   : integer;
192
      n_chroma_g : integer);
193
    port (
194
      clk    : in  std_logic;
195
      rst_n  : in  std_logic;
196
      ena_in : in  std_logic;
197
      cl_out : out std_logic);
198
  end component;
199
 
200
 
201
  type main_state_type is (idle, wait_quant_addr, wait_idct_addr, wait_control, wait_data, write_data);
202
  type result_send_type is (idle, send_av, send_data, send_last, send_rel_av, send_rel);
203
 
204
  -- States (results is quant is kind of state too )
205
  signal main_state        : main_state_type;
206
  signal result_send_state : result_send_type;
207
  signal result_is_quant_r : std_logic;
208
 
209
  -- Signals related to control word
210
  signal control_word_r : std_logic_vector(data_width_g-1 downto 0);
211
  alias intra_r         : std_logic is control_word_r(5);
212
  alias quant_param_r   : std_logic_vector(4 downto 0) is control_word_r(4 downto 0);
213
  signal loadQP_r       : std_logic;
214
 
215
  -- Some internal hibi signals
216
  signal hibi_re_i   : std_logic;
217
  signal hibi_re_r   : std_logic;
218
  signal hibi_we_i   : std_logic;
219
  signal hibi_we_r   : std_logic;
220
  signal hibi_av_r   : std_logic;
221
  signal hibi_data_r : std_logic_vector(data_width_g-1 downto 0);
222
 
223
  -- Signals to handle sending self release to rtm
224
  signal send_release_r : std_logic;
225
  signal release_sent_r : std_logic;
226
 
227
  -- Signals releated to fifos which store the result addresses
228
  signal addr_fifos_re_r    : std_logic;
229
  signal addr_fifo_q_we     : std_logic;
230
  signal addr_fifo_i_we     : std_logic;
231
  signal addr_ret_for_quant : std_logic_vector(data_width_g-1 downto 0);
232
  signal addr_ret_for_idct  : std_logic_vector(data_width_g-1 downto 0);
233
  signal addr_ret           : std_logic_vector(data_width_g-1 downto 0);
234
 
235
 
236
  -- For determing if a 8x8 block has only zeros ( skip 1st value of intra block )
237
  signal first_of_a_block_r : std_logic;
238
  signal quant_or_r         : std_logic_vector(n_blocks_per_req_c-1 downto 0);
239
  signal intra_old_r        : std_logic;
240
  signal send_or_value_r    : std_logic;
241
 
242
  -- For signalling dctQidct if we are ready to receive results or not
243
  signal ready_for_q_col_r : std_logic;
244
  signal ready_for_i_col_r : std_logic;
245
 
246
begin  -- rtl
247
 
248
  -----------------------------------------------------------------------------
249
 
250
  intra_out  <= intra_r;
251
  QP_out     <= quant_param_r;
252
  loadQP_out <= loadQP_r;
253
 
254
  -----------------------------------------------------------------------------
255
 
256
  cl_cnt_1 : cl_cnt
257
    generic map (
258
      n_luma_g   => 4,
259
      n_chroma_g => 2)
260
    port map (
261
      clk    => clk,
262
      rst_n  => rst_n,
263
      ena_in => loadQP_r,
264
      cl_out => chroma_out
265
      );
266
 
267
  -----------------------------------------------------------------------------
268
 
269
  fifo_tx_i : fifo
270
    generic map (
271
      data_width_g => data_width_g,
272
      depth_g      => tx_fifo_depth_c
273
      )
274
    port map (
275
      clk       => clk,
276
      rst_n     => rst_n,
277
      data_in   => tx_i_fifo_data_to_r,
278
      we_in     => tx_i_fifo_we,
279
      full_out  => tx_i_fifo_full,
280
      data_out  => tx_i_fifo_data_from,
281
      re_in     => tx_i_fifo_re,
282
      empty_out => tx_i_fifo_empty
283
      );
284
 
285
  -----------------------------------------------------------------------------
286
 
287
  fifo_tx_q : fifo
288
    generic map (
289
      data_width_g => data_width_g,
290
      depth_g      => tx_fifo_depth_c
291
      )
292
    port map (
293
      clk       => clk,
294
      rst_n     => rst_n,
295
      data_in   => tx_q_fifo_data_to_r,
296
      we_in     => tx_q_fifo_we,
297
      full_out  => tx_q_fifo_full,
298
      data_out  => tx_q_fifo_data_from,
299
      re_in     => tx_q_fifo_re,
300
      empty_out => tx_q_fifo_empty
301
      );
302
 
303
  addr_fifo_q : fifo
304
    generic map (
305
      data_width_g => data_width_g,
306
      depth_g      => 2  -- two addresses in mem (new and current)
307
      )
308
    port map (
309
      clk      => clk,
310
      rst_n    => rst_n,
311
      data_in  => hibi_data_in,
312
      we_in    => addr_fifo_q_we,
313
--      full_out  => tx_q_fifo_full,
314
      data_out => addr_ret_for_quant,
315
      re_in    => addr_fifos_re_r
316
--      empty_out => tx_q_fifo_empty
317
      );
318
 
319
  addr_fifo_i : fifo
320
    generic map (
321
      data_width_g => data_width_g,
322
      depth_g      => 2  -- two addresses in mem (new and current)
323
      )
324
    port map (
325
      clk      => clk,
326
      rst_n    => rst_n,
327
      data_in  => hibi_data_in,
328
      we_in    => addr_fifo_i_we,
329
--      full_out  => tx_q_fifo_full,
330
      data_out => addr_ret_for_idct,
331
      re_in    => addr_fifos_re_r
332
--      empty_out => tx_q_fifo_empty
333
      );
334
 
335
  -----------------------------------------------------------------------------
336
 
337
  quant_ready4col_out <= ready_for_q_col_r;  --2.8.
338
  idct_ready4col_out  <= ready_for_i_col_r;  --2.8.
339
 
340
  addr_fifo_q_we <= '1' when hibi_empty_in = '0' and hibi_av_in = '0' and main_state = wait_quant_addr
341
                    else '0';
342
  addr_fifo_i_we <= '1' when hibi_empty_in = '0' and hibi_av_in = '0' and main_state = wait_idct_addr
343
                    else '0';
344
 
345
  -----------------------------------------------------------------------------
346
 
347
-- This process handles the incoming requests and stores the data to fifo
348
-- for the dct
349
  main : process (clk, rst_n)
350
    variable value_sel_v : integer range 0 to data_width_g/dct_word_width_in_bus_c-1;
351
  begin  -- process main
352
    if rst_n = '0' then                 -- asynchronous reset (active low)
353
      control_word_r <= (others => '0');
354
      wr_dct_out     <= '0';
355
      hibi_re_r      <= '0';
356
      data_dct_out   <= (others => '0');
357
      loadQP_r       <= '0';
358
      main_state     <= idle;
359
      send_release_r <= '0';
360
      rx_counter_r   <= 0;
361
 
362
    elsif clk'event and clk = '1' then  -- rising clock edge
363
 
364
      loadQP_r <= '0';
365
 
366
      if release_sent_r = '1' then
367
        send_release_r <= '0';
368
      end if;
369
 
370
      case main_state is
371
 
372
        when idle =>
373
          wr_dct_out <= '0';
374
          hibi_re_r  <= '1';
375
          if hibi_empty_in = '0' and hibi_av_in = '1' then
376
            main_state <= wait_quant_addr;
377
          end if;
378
 
379
        when wait_quant_addr =>
380
 
381
          if hibi_empty_in = '0' and hibi_av_in = '0' then
382
            main_state <= wait_idct_addr;
383
          end if;
384
 
385
        when wait_idct_addr =>
386
          if hibi_empty_in = '0' and hibi_av_in = '0' then
387
            main_state <= wait_control;
388
          end if;
389
 
390
        when wait_control =>
391
          if hibi_empty_in = '0' and hibi_av_in = '0' then
392
            control_word_r <= hibi_data_in;
393
            hibi_re_r      <= '0';
394
            main_state     <= wait_data;
395
          end if;
396
 
397
        when wait_data =>
398
          wr_dct_out <= '0';
399
          hibi_re_r  <= '0';
400
          if dct_ready4col_in = '1' then
401
            main_state <= write_data;
402
          end if;
403
 
404
        when write_data =>
405
          wr_dct_out <= '0';
406
          hibi_re_r  <= '0';
407
 
408
          value_sel_v := rx_counter_r mod (data_width_g/dct_word_width_in_bus_c);
409
 
410
          if hibi_empty_in = '0' and hibi_av_in = '1' and hibi_re_r = '0' then
411
            hibi_re_r <= '1';
412
          end if;
413
 
414
          if hibi_empty_in = '0' and hibi_av_in = '0' and (value_sel_v /= data_width_g/dct_word_width_in_bus_c-1 or hibi_re_i = '1') then
415
 
416
            wr_dct_out <= '1';
417
 
418
            for i in 0 to data_width_g/dct_word_width_in_bus_c-1 loop
419
              if i = value_sel_v then
420
                data_dct_out <= hibi_data_in(i*dct_word_width_in_bus_c+dct_width_g-1 downto i*dct_word_width_in_bus_c);
421
              end if;
422
            end loop;
423
 
424
            if data_width_g/dct_word_width_in_bus_c = 1 then
425
              hibi_re_r <= '1';
426
            else
427
 
428
              if value_sel_v = data_width_g/dct_word_width_in_bus_c-1-1 then
429
                hibi_re_r <= '1';
430
              end if;
431
 
432
            end if;
433
 
434
            if rx_counter_r mod 8 = 7 then
435
              main_state <= wait_data;
436
            end if;
437
 
438
            if rx_counter_r mod 64 = 63 then
439
              loadQP_r <= '1';
440
            end if;
441
 
442
            if rx_counter_r = rx_elements_c-1 then
443
              rx_counter_r   <= 0;
444
              send_release_r <= '1';
445
              main_state     <= idle;
446
            else
447
              rx_counter_r <= rx_counter_r + 1;
448
            end if;
449
 
450
            --        else
451
--            hibi_re_r <= '1';
452
          end if;
453
 
454
      end case;
455
 
456
    end if;
457
  end process main;
458
 
459
  -----------------------------------------------------------------------------
460
 
461
  hibi_re_i   <= hibi_re_r and (not hibi_empty_in);
462
  hibi_re_out <= hibi_re_i;
463
 
464
  -----------------------------------------------------------------------------
465
 
466
 
467
  -------------------------------------------------------------------------------
468
  -- Process which handles the result idct data writing to corresponding tx fifo
469
  -------------------------------------------------------------------------------
470
  output_to_fifo_i : process (clk, rst_n)
471
  begin  -- process dct_to_fifo
472
    if rst_n = '0' then                 -- asynchronous reset (active low)
473
 
474
      tx_i_fifo_value_sel_r <= 0;
475
      tx_i_fifo_data_to_r   <= (others => '0');
476
      tx_i_fifo_we          <= '0';
477
 
478
    elsif clk'event and clk = '1' then  -- rising clock edge
479
 
480
      tx_i_fifo_we <= '0';
481
      if wr_idct_in = '1' then
482
 
483
        tx_i_fifo_we <= '0';
484
        assert tx_i_fifo_full = '0' report "TX I FIFO FULL!" severity failure;
485
 
486
        for i in 0 to tx_fifo_value_sel_max_c-1 loop
487
          if i = tx_i_fifo_value_sel_r then
488
            tx_i_fifo_data_to_r((i+1)*output_word_width_c-1 downto i*output_word_width_c) <= std_logic_vector(resize(signed(data_idct_in), output_word_width_c));
489
          end if;
490
        end loop;
491
 
492
 
493
        if tx_i_fifo_value_sel_r = tx_fifo_value_sel_max_c-1 then
494
          tx_i_fifo_value_sel_r <= 0;
495
          tx_i_fifo_we          <= '1';
496
        else
497
          tx_i_fifo_value_sel_r <= tx_i_fifo_value_sel_r + 1;
498
        end if;
499
 
500
      end if;
501
 
502
    end if;
503
  end process output_to_fifo_i;
504
 
505
  -------------------------------------------------------------------------------
506
  -- Process which handles the result quant data writing to corresponding tx fifo
507
  -------------------------------------------------------------------------------
508
  output_to_fifo_q : process (clk, rst_n)
509
    variable intra_v : std_logic;
510
  begin  -- process dct_to_fifo
511
    if rst_n = '0' then                 -- asynchronous reset (active low)
512
 
513
      tx_q_fifo_value_sel_r <= 0;
514
      tx_q_fifo_data_to_r   <= (others => '0');
515
      tx_q_fifo_we          <= '0';
516
 
517
    elsif clk'event and clk = '1' then  -- rising clock edge
518
 
519
      tx_q_fifo_we <= '0';
520
      if wr_quant_in = '1' then
521
 
522
        tx_q_fifo_we <= '0';
523
        assert tx_q_fifo_full = '0' report "TX Q FIFO FULL!" severity failure;
524
 
525
 
526
        -- The following if statement is also in the zero check process
527
        if result_block_counter_r = 0 then
528
          intra_v := intra_r;
529
          -- Commented out intra_old <= intra_r assignment because
530
          -- it is in the zero check process
531
        else
532
          intra_v := intra_old_r;
533
        end if;
534
 
535
 
536
        for i in 0 to tx_fifo_value_sel_max_c-1 loop
537
          if i = tx_q_fifo_value_sel_r then
538
            -- Lets treat the first coeff of an intra block as a unsigned
539
            -- (1-254 according to the quant specs found in IQuant.vhd)
540
            if (first_of_a_block_r = '1' and intra_v = '1') then
541
              tx_q_fifo_data_to_r((i+1)*output_word_width_c-1 downto i*output_word_width_c) <= std_logic_vector(resize(unsigned(data_quant_in), output_word_width_c));
542
            else
543
              tx_q_fifo_data_to_r((i+1)*output_word_width_c-1 downto i*output_word_width_c) <= std_logic_vector(resize(signed(data_quant_in), output_word_width_c));
544
            end if;
545
          end if;
546
        end loop;
547
 
548
        if tx_q_fifo_value_sel_r = tx_fifo_value_sel_max_c-1 then
549
          tx_q_fifo_value_sel_r <= 0;
550
          tx_q_fifo_we          <= '1';
551
        else
552
          tx_q_fifo_value_sel_r <= tx_q_fifo_value_sel_r + 1;
553
        end if;
554
 
555
      end if;
556
 
557
    end if;
558
  end process output_to_fifo_q;
559
 
560
 
561
  -----------------------------------------------------------------------------
562
  -- Depending on the result_is_quant_r signal, tx_fifo signals are connected
563
  -- to either of the two transmit fifos (quant or idct)
564
  -----------------------------------------------------------------------------
565
 
566
  q_i_fifo_mux_demux : process (tx_i_fifo_full, tx_q_fifo_full, tx_q_fifo_empty, tx_i_fifo_empty, tx_fifo_re, tx_q_fifo_data_from, tx_i_fifo_data_from, result_is_quant_r, addr_ret_for_idct, addr_ret_for_quant)
567
  begin  -- process q_i_fifo_mux
568
    tx_q_fifo_re <= '0';
569
    tx_i_fifo_re <= '0';
570
 
571
    if result_is_quant_r = '1' then
572
      tx_q_fifo_re <= tx_fifo_re;
573
 
574
      tx_fifo_full      <= tx_q_fifo_full;
575
      tx_fifo_empty     <= tx_q_fifo_empty;
576
      tx_fifo_data_from <= tx_q_fifo_data_from;
577
 
578
      addr_ret <= addr_ret_for_quant;
579
    else
580
      tx_i_fifo_re <= tx_fifo_re;
581
 
582
      tx_fifo_data_from <= tx_i_fifo_data_from;
583
      tx_fifo_full      <= tx_i_fifo_full;
584
      tx_fifo_empty     <= tx_i_fifo_empty;
585
 
586
      addr_ret <= addr_ret_for_idct;
587
    end if;
588
 
589
  end process q_i_fifo_mux_demux;
590
 
591
  -----------------------------------------------------------------------------
592
 
593
  hibi_we_i   <= hibi_we_r and (not hibi_full_in) and ((not tx_fifo_empty) or release_sent_r or send_or_value_r);
594
  hibi_we_out <= hibi_we_i;
595
 
596
  hibi_av_out <= hibi_av_r;
597
 
598
  tx_fifo_re <= tx_fifo_re_r and (not hibi_full_in) and (not tx_fifo_empty);
599
 
600
  -- Choose hibi_data_out depending on the state and hibi_av_out (_r)
601
  tx_fifo_read : process (result_send_state, hibi_data_r, tx_fifo_data_from, hibi_av_r)
602
  begin  -- process tx_fifo_i_read
603
    if (result_send_state = send_data) and hibi_av_r = '0' then
604
      hibi_data_out <= tx_fifo_data_from;
605
    else
606
      hibi_data_out <= hibi_data_r;
607
    end if;
608
  end process tx_fifo_read;
609
 
610
  -----------------------------------------------------------------------------
611
  -- ZERO CHECK PROCESS
612
  -- Determine if incoming quant data has only zeros or not
613
  -----------------------------------------------------------------------------
614
  zero_check : process (clk, rst_n)
615
    variable intra_v : std_logic;
616
  begin  -- process zero_check
617
    if rst_n = '0' then                 -- asynchronous reset (active low)
618
      quant_or_r         <= (others => '0');
619
      first_of_a_block_r <= '1';
620
      intra_old_r        <= '0';
621
    elsif clk'event and clk = '1' then  -- rising clock edge
622
 
623
      intra_v := '0';
624
 
625
      if wr_quant_in = '1' then
626
 
627
 
628
        -- These same if-statements are also in quant result write process
629
        if result_block_counter_r = 0 then
630
          intra_v     := intra_r;
631
          intra_old_r <= intra_r;
632
        else
633
          intra_v := intra_old_r;
634
        end if;
635
 
636
        if not (first_of_a_block_r = '1' and intra_v = '1') then
637
          quant_or_r(0) <= quant_or_r(0) or or_reduce(data_quant_in);
638
        end if;
639
 
640
        if first_of_a_block_r = '1' then
641
          first_of_a_block_r <= '0';
642
        end if;
643
 
644
      end if;
645
 
646
      if result_send_state = send_last and result_is_quant_r = '1' then
647
        first_of_a_block_r <= '1';
648
        quant_or_r         <= quant_or_r(n_blocks_per_req_c-2 downto 0) & '0';
649
      end if;
650
 
651
 
652
    end if;
653
  end process zero_check;
654
 
655
  -----------------------------------------------------------------------------
656
  -- SEND RESULTS OVER HIBI
657
  -----------------------------------------------------------------------------
658
  hibi_send_proc : process (clk, rst_n)
659
  begin  -- process hibi_send_proc
660
    if rst_n = '0' then                 -- asynchronous reset (active low)
661
      hibi_data_r            <= (others => '0');
662
      hibi_comm_out          <= std_logic_vector(to_unsigned(0, comm_width_g));
663
      hibi_we_r              <= '0';
664
      hibi_av_r              <= '0';
665
      tx_fifo_re_r           <= '0';
666
      tx_data_counter_r      <= 0;
667
      release_sent_r         <= '0';
668
      result_is_quant_r      <= '1';
669
      addr_fifos_re_r        <= '0';
670
      send_or_value_r        <= '0';
671
      result_send_state      <= idle;
672
      result_block_counter_r <= 0;
673
      ready_for_q_col_r      <= '1';
674
      ready_for_i_col_r      <= '1';
675
 
676
    elsif clk'event and clk = '1' then  -- rising clock edge
677
 
678
      addr_fifos_re_r <= '0';
679
 
680
      -- If incoming data from dctQidct, let's set the ready signals low
681
      if wr_quant_in = '1' then
682
        ready_for_q_col_r <= '0';
683
      end if;
684
      if wr_idct_in = '1' then
685
        ready_for_i_col_r <= '0';
686
      end if;
687
 
688
 
689
      case result_send_state is
690
 
691
        -- Do nothing unless there is something in transmit fifo or release is
692
        -- requested
693
        when idle =>
694
          if tx_fifo_empty = '0' then
695
            result_send_state <= send_av;
696
          end if;
697
 
698
          if send_release_r = '1' and use_self_rel_g /= 0 then
699
            result_send_state <= send_rel_av;
700
          end if;
701
 
702
          -- Send self release address valid (+2 for release to rtm)
703
        when send_rel_av =>
704
          release_sent_r    <= '1';
705
          hibi_av_r         <= '1';
706
          hibi_we_r         <= '1';
707
          hibi_comm_out     <= std_logic_vector(to_unsigned(3, comm_width_g));
708
          hibi_data_r       <= std_logic_vector(to_unsigned(rtm_address_g+2, data_width_g));
709
          result_send_state <= send_rel;
710
 
711
          -- Send self release data (own address)
712
        when send_rel =>
713
          if hibi_we_i = '1' then
714
            hibi_av_r   <= '0';
715
            hibi_data_r <= std_logic_vector(to_unsigned(own_address_g, data_width_g));
716
            if hibi_av_r = '0' then
717
              hibi_data_r       <= (others => '0');
718
              hibi_we_r         <= '0';
719
              hibi_comm_out     <= (others => '0');
720
              release_sent_r    <= '0';
721
              result_send_state <= idle;
722
            end if;
723
          end if;
724
 
725
          -- Send address valid in the beginning of every 8x8 block
726
        when send_av =>
727
          hibi_av_r     <= '1';
728
          hibi_we_r     <= '1';
729
          hibi_comm_out <= std_logic_vector(to_unsigned(2, comm_width_g));
730
          hibi_data_r   <= addr_ret;
731
 
732
          result_send_state <= send_data;
733
 
734
        when send_data =>
735
 
736
          -- If last sending was ok.
737
          if hibi_we_i = '1' then
738
            tx_fifo_re_r <= '1';
739
            hibi_av_r    <= '0';
740
 
741
            -- If address is sent
742
            if hibi_av_r = '0' then
743
 
744
              -- If 8x8 block sending is ready
745
              if tx_data_counter_r = n_values_in_block_c-1 then  -- 0..31
746
                tx_data_counter_r <= 0;
747
 
748
                -- If we are finished sending the last 8x8 block (idct in fact)
749
                if result_block_counter_r = result_block_count_c-1 then  --0..11
750
                  result_block_counter_r <= 0;
751
                  addr_fifos_re_r        <= '1';
752
                else
753
                  result_block_counter_r <= result_block_counter_r + 1;
754
                end if;
755
 
756
                hibi_av_r       <= '0';
757
                hibi_comm_out   <= (others => '0');
758
                hibi_we_r       <= '0';
759
                hibi_data_r     <= (others => '0');
760
                tx_fifo_re_r    <= '0';
761
                send_or_value_r <= '0';
762
 
763
                -- If we are finished sending the last QUANT block,
764
                -- let's send the OR-value which determines if QUANT blocks
765
                -- has zeros.
766
                if result_block_counter_r = result_block_count_c-2 then
767
                  hibi_we_r                                  <= '1';
768
                  send_or_value_r                            <= '1';
769
                  hibi_data_r(n_blocks_per_req_c-1 downto 0) <= quant_or_r;
770
                  hibi_comm_out                              <= std_logic_vector(to_unsigned(2, comm_width_g));
771
                end if;
772
 
773
                result_send_state <= send_last;
774
 
775
              else
776
                tx_data_counter_r <= tx_data_counter_r + 1;
777
              end if;
778
 
779
              -- After every 8 values, we set the ready signal back on
780
              if tx_data_counter_r mod (8/tx_fifo_value_sel_max_c) = (8/tx_fifo_value_sel_max_c)-1 then
781
                if result_is_quant_r = '1' then
782
                  ready_for_q_col_r <= '1';
783
                else
784
                  ready_for_i_col_r <= '1';
785
                end if;
786
              end if;
787
 
788
            end if;
789
 
790
          end if;
791
 
792
          -- In this state, the or word is being sent, if send_or_value_r is high.
793
        when send_last =>
794
          if send_or_value_r = '0' or hibi_we_i = '1' then
795
            send_or_value_r   <= '0';
796
            hibi_we_r         <= '0';
797
            hibi_data_r       <= (others => '0');
798
            hibi_comm_out     <= (others => '0');
799
            result_is_quant_r <= not result_is_quant_r;
800
            result_send_state <= idle;
801
          end if;
802
 
803
      end case;
804
 
805
    end if;
806
  end process hibi_send_proc;
807
 
808
end rtl;
809
 

powered by: WebSVN 2.1.0

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