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/] [dctqidct/] [1.0/] [hdl/] [quantizer/] [IQuant.vhd] - Blame information for rev 176

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
------------------------------------------------------------------------------
2
-- TUT / DCS
3
-------------------------------------------------------------------------------
4
-- Author               : Timo Alho
5
-- e-mail               : timo.a.alho@tut.fi
6
-- Date                 : 22.06.2004 09:26:51
7
-- File                 : IQuant.vhd
8
-- Design               : MPEG4 Quantizer / Inverse Quantizer (H263 -method)
9
------------------------------------------------------------------------------
10
-- Description  :
11
-- Performs MPEG4 quantization and inverse quantization (H263 -method)
12
--
13
-- Quantization is defined as follows:
14
-- 1) If intra frame and DC -coefficient, then
15
--    qcoeff(0) = coeff(0)//dc_scaler, 
16
--    where dc_scaler depends on QP as explained in following table
17
--
18
--                  dc_scaler
19
-- ---------------------------------------------------
20
-- QP          | 1->4  | 5->8    | 9->24   | 25->31   |           
21
-- ---------------------------------------------------
22
-- LUMINANCE   |  8    |  2*QP   | QP+8    | 2*QP-16  |
23
-- CHROMINANCE |  8    |     (QP+13)/2     | QP-6     |
24
-- ---------------------------------------------------
25
 
26
-- 2) If intra frame and AC -coefficient, then
27
-- qcoeff(i) = sign(coeff(i)) * abs(coeff(i)/(2*QP)), where i=(1->63)
28
-- 3) If inter frame, then
29
-- qcoeff(i) = sign(coeff(i)) * (abs(coeff(i))-QP/2)/(2*QP), where i=(0->63)
30
--
31
-- For intra-DC frame, qcoeff(0) is clipped to a range from 1 to 254.
32
-- Otherwise qcoeff(i) is clipped between -127 and 127
33
--
34
-- Inverse quantization is defined as follows:
35
-- 1) If intra frame and DC -coefficient, then
36
-- rcoeff(0) = dc_scaler*qcoeff(0)
37
-- 2) otherwise
38
-- rcoeff(i) = sign(qcoeff(i))*(QP*(2*abs(qcoeff(i)+1)), if QP is odd
39
-- rcoeff(i) = sign(qcoeff(i))*(QP*(2*abs(qcoeff(i)+1) - 1), if QP is even
40
--
41
-- rcoeff(i) is NOT clipped between -2048 and 2047, however if input data is
42
-- true output of DCT, it is not needed.
43
--
44
-- sign(x) = 0, if x=0
45
-- 1, if x>0
46
-- -1, if x<0
47
-- This implementation of quantizer/inverse quantizer is pipelined. It can be
48
-- used at data rate.
49
------------------------------------------------------------------------------
50
-- Version history:
51
-- 1.0 Initial version
52
-- 1.1 Quantizer parameter input modified.
53
------------------------------------------------------------------------------
54
LIBRARY ieee;
55
USE ieee.std_logic_1164.ALL;
56
USE ieee.std_logic_arith.ALL;
57
LIBRARY quantizer;
58
USE quantizer.Quantizer_pkg.ALL;
59
 
60
ENTITY IQuant IS
61
  GENERIC(
62
    qmulw_g   :     integer := 16
63
    );
64
  PORT(
65
    clk       : IN  std_logic;
66
    rst_n     : IN  std_logic;
67
    --'1' if input data is to be quantized
68
    --as DC -coefficient
69
    dc        : IN  std_logic;
70
    --when active, loads new QP+intra+chroma into quantizer
71
    loadQP    : IN  std_logic;
72
    --as intra -coefficient
73
    intra     : IN  std_logic;
74
    --'1' if input data is to be quantized as a chrominance block
75
    chroma    : IN  std_logic;
76
    -- Quantizer parameter
77
    qp        : IN  std_logic_vector (4 DOWNTO 0);
78
    --write in
79
    wr_in     : IN  std_logic;
80
    --input coefficient
81
    coeff_in  : IN  std_logic_vector (QUANT_inputw_co-1 DOWNTO 0);
82
    --quantized coefficient
83
    rcoeff    : OUT std_logic_vector (IQUANT_resultw_co-1 DOWNTO 0);
84
    --inverse quantized coefficient
85
    qcoeff    : OUT std_logic_vector (QUANT_resultw_co-1 DOWNTO 0);
86
    --quantized coefficient write out
87
    q_wr_out  : OUT std_logic;
88
    --inverse quantized coefficient write out
89
    iq_wr_out : OUT std_logic
90
    );
91
 
92
-- Declarations
93
 
94
END IQuant;
95
 
96
 
97
ARCHITECTURE rtl OF IQuant IS
98
 
99
  --constant coefficients (1/(QP))
100
  TYPE Rom32x16 IS ARRAY (0 TO 31) OF unsigned(16-1 DOWNTO 0);
101
  CONSTANT ROM_INV_QP : Rom32x16 := (
102
    conv_unsigned(16384, 16),
103
    conv_unsigned(65535, 16),
104
    conv_unsigned(32768, 16),
105
    conv_unsigned(21845, 16),
106
    conv_unsigned(16384, 16),
107
    conv_unsigned(13107, 16),
108
    conv_unsigned(10923, 16),
109
    conv_unsigned(9362, 16),
110
    conv_unsigned(8192, 16),
111
    conv_unsigned(7282, 16),
112
    conv_unsigned(6554, 16),
113
    conv_unsigned(5958, 16),
114
    conv_unsigned(5461, 16),
115
    conv_unsigned(5041, 16),
116
    conv_unsigned(4681, 16),
117
    conv_unsigned(4369, 16),
118
    conv_unsigned(4096, 16),
119
    conv_unsigned(3855, 16),
120
    conv_unsigned(3641, 16),
121
    conv_unsigned(3449, 16),
122
    conv_unsigned(3277, 16),
123
    conv_unsigned(3121, 16),
124
    conv_unsigned(2979, 16),
125
    conv_unsigned(2849, 16),
126
    conv_unsigned(2731, 16),
127
    conv_unsigned(2621, 16),
128
    conv_unsigned(2521, 16),
129
    conv_unsigned(2427, 16),
130
    conv_unsigned(2341, 16),
131
    conv_unsigned(2260, 16),
132
    conv_unsigned(2185, 16),
133
    conv_unsigned(2114, 16));
134
 
135
  --constant coefficients 2*(1/DCscaler)
136
  TYPE Rom64x16 IS ARRAY (0 TO 63) OF unsigned(16-1 DOWNTO 0);
137
  CONSTANT ROM_INV_DCSCALER : Rom64x16 := (
138
    conv_unsigned(0, 16),
139
    conv_unsigned(16384, 16),
140
    conv_unsigned(16384, 16),
141
    conv_unsigned(16384, 16),
142
    conv_unsigned(16384, 16),
143
    conv_unsigned(13108, 16),
144
    conv_unsigned(10922, 16),
145
    conv_unsigned(9362, 16),
146
    conv_unsigned(8192, 16),
147
    conv_unsigned(7710, 16),
148
    conv_unsigned(7282, 16),
149
    conv_unsigned(6898, 16),
150
    conv_unsigned(6554, 16),
151
    conv_unsigned(6242, 16),
152
    conv_unsigned(5958, 16),
153
    conv_unsigned(5698, 16),
154
    conv_unsigned(5462, 16),
155
    conv_unsigned(5242, 16),
156
    conv_unsigned(5042, 16),
157
    conv_unsigned(4854, 16),
158
    conv_unsigned(4682, 16),
159
    conv_unsigned(4520, 16),
160
    conv_unsigned(4370, 16),
161
    conv_unsigned(4228, 16),
162
    conv_unsigned(4096, 16),
163
    conv_unsigned(3856, 16),
164
    conv_unsigned(3640, 16),
165
    conv_unsigned(3450, 16),
166
    conv_unsigned(3276, 16),
167
    conv_unsigned(3120, 16),
168
    conv_unsigned(2978, 16),
169
    conv_unsigned(2850, 16),
170
    conv_unsigned(0, 16),
171
    conv_unsigned(16384, 16),
172
    conv_unsigned(16384, 16),
173
    conv_unsigned(16384, 16),
174
    conv_unsigned(16384, 16),
175
    conv_unsigned(14564, 16),
176
    conv_unsigned(14564, 16),
177
    conv_unsigned(13108, 16),
178
    conv_unsigned(13108, 16),
179
    conv_unsigned(11916, 16),
180
    conv_unsigned(11916, 16),
181
    conv_unsigned(10922, 16),
182
    conv_unsigned(10922, 16),
183
    conv_unsigned(10082, 16),
184
    conv_unsigned(10082, 16),
185
    conv_unsigned(9362, 16),
186
    conv_unsigned(9362, 16),
187
    conv_unsigned(8738, 16),
188
    conv_unsigned(8738, 16),
189
    conv_unsigned(8192, 16),
190
    conv_unsigned(8192, 16),
191
    conv_unsigned(7710, 16),
192
    conv_unsigned(7710, 16),
193
    conv_unsigned(7282, 16),
194
    conv_unsigned(7282, 16),
195
    conv_unsigned(6898, 16),
196
    conv_unsigned(6554, 16),
197
    conv_unsigned(6242, 16),
198
    conv_unsigned(5958, 16),
199
    conv_unsigned(5698, 16),
200
    conv_unsigned(5462, 16),
201
    conv_unsigned(5242, 16));
202
 
203
 
204
  --constant coefficients (DCscaler)
205
  TYPE Rom64x6 IS ARRAY (0 TO 63) OF unsigned(6-1 DOWNTO 0);
206
  CONSTANT ROM_DCSCALER : Rom64x6 := (
207
    conv_unsigned(0, 6),
208
    conv_unsigned(8, 6),
209
    conv_unsigned(8, 6),
210
    conv_unsigned(8, 6),
211
    conv_unsigned(8, 6),
212
    conv_unsigned(10, 6),
213
    conv_unsigned(12, 6),
214
    conv_unsigned(14, 6),
215
    conv_unsigned(16, 6),
216
    conv_unsigned(17, 6),
217
    conv_unsigned(18, 6),
218
    conv_unsigned(19, 6),
219
    conv_unsigned(20, 6),
220
    conv_unsigned(21, 6),
221
    conv_unsigned(22, 6),
222
    conv_unsigned(23, 6),
223
    conv_unsigned(24, 6),
224
    conv_unsigned(25, 6),
225
    conv_unsigned(26, 6),
226
    conv_unsigned(27, 6),
227
    conv_unsigned(28, 6),
228
    conv_unsigned(29, 6),
229
    conv_unsigned(30, 6),
230
    conv_unsigned(31, 6),
231
    conv_unsigned(32, 6),
232
    conv_unsigned(34, 6),
233
    conv_unsigned(36, 6),
234
    conv_unsigned(38, 6),
235
    conv_unsigned(40, 6),
236
    conv_unsigned(42, 6),
237
    conv_unsigned(44, 6),
238
    conv_unsigned(46, 6),
239
    conv_unsigned(0, 6),
240
    conv_unsigned(8, 6),
241
    conv_unsigned(8, 6),
242
    conv_unsigned(8, 6),
243
    conv_unsigned(8, 6),
244
    conv_unsigned(9, 6),
245
    conv_unsigned(9, 6),
246
    conv_unsigned(10, 6),
247
    conv_unsigned(10, 6),
248
    conv_unsigned(11, 6),
249
    conv_unsigned(11, 6),
250
    conv_unsigned(12, 6),
251
    conv_unsigned(12, 6),
252
    conv_unsigned(13, 6),
253
    conv_unsigned(13, 6),
254
    conv_unsigned(14, 6),
255
    conv_unsigned(14, 6),
256
    conv_unsigned(15, 6),
257
    conv_unsigned(15, 6),
258
    conv_unsigned(16, 6),
259
    conv_unsigned(16, 6),
260
    conv_unsigned(17, 6),
261
    conv_unsigned(17, 6),
262
    conv_unsigned(18, 6),
263
    conv_unsigned(18, 6),
264
    conv_unsigned(19, 6),
265
    conv_unsigned(20, 6),
266
    conv_unsigned(21, 6),
267
    conv_unsigned(22, 6),
268
    conv_unsigned(23, 6),
269
    conv_unsigned(24, 6),
270
    conv_unsigned(25, 6));
271
 
272
--registered input
273
  SIGNAL coeff_in_r : std_logic_vector(QUANT_inputw_co-1 DOWNTO 0);
274
--register DC-signal
275
  SIGNAL DC_r : std_logic;
276
 
277
--result of abs(2*coeff_in)
278
  SIGNAL abs_input   : unsigned(QUANT_inputw_co DOWNTO 0);
279
--registered abs_input
280
  SIGNAL abs_input_r : unsigned(QUANT_inputw_co DOWNTO 0);
281
 
282
--result of quantizer "pre-subtraction"
283
  SIGNAL q_pre_sub   : unsigned(QUANT_inputw_co DOWNTO 0);
284
--registered q_pre_sub
285
  SIGNAL q_pre_sub_r : unsigned(QUANT_inputw_co DOWNTO 0);
286
 
287
  SIGNAL quantizer_multiplier   : unsigned(qmulw_g-1 DOWNTO 0);
288
  SIGNAL quantizer_multiplier_r : unsigned(qmulw_g-1 DOWNTO 0);
289
 
290
  SIGNAL invquant_multiplier   : unsigned(5 DOWNTO 0);
291
  SIGNAL invquant_multiplier_r : unsigned(5 DOWNTO 0);
292
 
293
--sign of input coefficient, sign <= sign(coeff_in)
294
  SIGNAL sign : std_logic;
295
 
296
--'1' if quantized data is zero
297
  SIGNAL zero_quant : std_logic;
298
 
299
--result of quantizer multiplication
300
  SIGNAL q_mul   : unsigned(QUANT_resultw_co+2 DOWNTO 0);
301
--registered q_mul
302
  SIGNAL q_mul_r : unsigned(QUANT_resultw_co+2 DOWNTO 0);
303
 
304
--result of clipping
305
  SIGNAL q_clip   : unsigned(QUANT_resultw_co-1 DOWNTO 0);
306
--registered q_clip
307
  SIGNAL q_clip_r : unsigned(QUANT_resultw_co-1 DOWNTO 0);
308
 
309
--result of quantizer
310
  SIGNAL q_result   : std_logic_vector(QUANT_resultw_co-1 DOWNTO 0);
311
--registered q_result
312
  SIGNAL q_result_r : std_logic_vector(QUANT_resultw_co-1 DOWNTO 0);
313
 
314
 
315
--QP loaded into input registers
316
  SIGNAL QP_loaded     : std_logic_vector(4 DOWNTO 0);
317
--chroma loaded into input register
318
  SIGNAL chroma_loaded : std_logic;
319
--intra loaded into input register
320
  SIGNAL intra_loaded  : std_logic;
321
 
322
--Active QP
323
  SIGNAL QP_active     : std_logic_vector(4 DOWNTO 0);
324
--Active chroma
325
  SIGNAL chroma_active : std_logic;
326
--Active intra
327
  SIGNAL intra_active  : std_logic;
328
 
329
 
330
 
331
--inverse of QP
332
  SIGNAL inv_QP : unsigned(qmulw_g-1 DOWNTO 0);
333
 
334
--inverse of DCscaler
335
  SIGNAL inv_DCscaler : unsigned(qmulw_g-1 DOWNTO 0);
336
 
337
--DCscaler
338
  SIGNAL DCscaler : unsigned(5 DOWNTO 0);
339
 
340
--result of of inv_quantizer multiplication
341
  SIGNAL iq_mul   : unsigned(IQUANT_resultw_co DOWNTO 0);
342
--registered iq_mul
343
  SIGNAL iq_mul_r : unsigned(IQUANT_resultw_co DOWNTO 0);
344
 
345
--result of of inv_quantizer "post-subtraction"
346
  SIGNAL iq_post_sub   : unsigned(IQUANT_resultw_co-1 DOWNTO 0);
347
--registered iq_post_sub
348
  SIGNAL iq_post_sub_r : unsigned(IQUANT_resultw_co-1 DOWNTO 0);
349
 
350
--registered rom addressess
351
  SIGNAL addr_inv_qp_r       : std_logic_vector(4 DOWNTO 0);
352
  SIGNAL addr_inv_dcscaler_r : std_logic_vector(5 DOWNTO 0);
353
  SIGNAL addr_DCscaler_r     : std_logic_vector(5 DOWNTO 0);
354
 
355
--delay lines
356
  SIGNAL sign_delay_r     : std_logic_vector(5 DOWNTO 0);
357
  SIGNAL out_delay_r      : std_logic_vector(6 DOWNTO 0);
358
  SIGNAL intra_dc_delay_r : std_logic_vector(4 DOWNTO 0);
359
  SIGNAL r_zero_delay_r   : std_logic_vector(1 DOWNTO 0);
360
 
361
BEGIN
362
 
363
  -- purpose: registered address for ROM access
364
  -- type   : sequential
365
  -- inputs : clk, addr
366
  -- outputs: addr_r
367
  address_clk : PROCESS (clk)
368
  BEGIN  -- PROCESS address_clk
369
    IF clk'event AND clk = '1' THEN     -- rising clock edge
370
      addr_inv_qp_r       <= QP_active;
371
      addr_inv_dcscaler_r <= chroma_active & QP_active;
372
      addr_DCscaler_r     <= chroma_active & QP_active;
373
    END IF;
374
  END PROCESS address_clk;
375
 
376
  clocked : PROCESS (clk, rst_n)
377
  BEGIN  -- PROCESS clocked
378
    IF rst_n = '0' THEN                 -- asynchronous reset (active low)
379
      coeff_in_r <= (OTHERS => '0');
380
 
381
      abs_input_r <= (OTHERS => '0');
382
      q_pre_sub_r <= (OTHERS => '0');
383
      q_mul_r     <= (OTHERS => '0');
384
      q_clip_r    <= (OTHERS => '0');
385
      q_result_r  <= (OTHERS => '0');
386
 
387
      iq_mul_r      <= (OTHERS => '0');
388
      iq_post_sub_r <= (OTHERS => '0');
389
 
390
      out_delay_r      <= (OTHERS => '0');
391
      sign_delay_r     <= (OTHERS => '0');
392
      intra_dc_delay_r <= (OTHERS => '0');
393
      r_zero_delay_r   <= (OTHERS => '0');
394
 
395
      quantizer_multiplier_r <= (OTHERS => '0');
396
      invquant_multiplier_r  <= (OTHERS => '0');
397
 
398
    ELSIF clk'event AND clk = '1' THEN  -- rising clock edge
399
      quantizer_multiplier_r <= quantizer_multiplier;
400
      invquant_multiplier_r  <= invquant_multiplier;
401
 
402
      --to decrease switching activity (=power consumption)
403
      --input register is hold constant when valid data is not available.
404
      IF (wr_in = '1') THEN
405
        coeff_in_r           <= coeff_in;
406
        DC_r <= DC;
407
      ELSE
408
        coeff_in_r           <= coeff_in_r;
409
        DC_r <= DC_r;
410
      END IF;
411
 
412
      --clk0
413
      out_delay_r(0)      <= wr_in;
414
 
415
 
416
      --clk1
417
      abs_input_r         <= abs_input;
418
      sign_delay_r(0)     <= sign;
419
      intra_dc_delay_r(0) <= DC_r AND intra_active;
420
      out_delay_r(1)      <= out_delay_r(0);
421
 
422
      --clk2
423
      q_pre_sub_r         <= q_pre_sub;
424
      sign_delay_r(1)     <= sign_delay_r(0);
425
      intra_dc_delay_r(1) <= intra_dc_delay_r(0);
426
      out_delay_r(2)      <= out_delay_r(1);
427
 
428
      --clk3
429
      q_mul_r             <= q_mul;
430
      sign_delay_r(2)     <= sign_delay_r(1);
431
      intra_dc_delay_r(2) <= intra_dc_delay_r(1);
432
      out_delay_r(3)      <= out_delay_r(2);
433
 
434
      --clk4
435
      q_clip_r            <= q_clip;
436
      sign_delay_r(3)     <= sign_delay_r(2);
437
      intra_dc_delay_r(3) <= intra_dc_delay_r(2);
438
      out_delay_r(4)      <= out_delay_r(3);
439
 
440
      --clk5
441
      q_result_r          <= q_result;
442
      iq_mul_r            <= iq_mul;
443
      sign_delay_r(4)     <= sign_delay_r(3);
444
      intra_dc_delay_r(4) <= intra_dc_delay_r(3);
445
      out_delay_r(5)      <= out_delay_r(4);
446
      r_zero_delay_r(0)   <= zero_quant;
447
 
448
      --clk6
449
      iq_post_sub_r     <= iq_post_sub;
450
      sign_delay_r(5)   <= sign_delay_r(4);
451
      out_delay_r(6)    <= out_delay_r(5);
452
      r_zero_delay_r(1) <= r_zero_delay_r(0);
453
 
454
    END IF;
455
  END PROCESS clocked;
456
 
457
  -- purpose: loads QP value when loadQP active, bypass loaded QP value to QP_
458
  -- active register, when DC active
459
  QP_loader : PROCESS (clk, rst_n)
460
  BEGIN  -- PROCESS QP_loader
461
    IF rst_n = '0' THEN                 -- asynchronous reset (active low)
462
      QP_loaded     <= (OTHERS => '0');
463
      chroma_loaded <= '0';
464
      intra_loaded  <= '0';
465
 
466
      QP_active     <= (OTHERS => '0');
467
      chroma_active <= '0';
468
      intra_active  <= '0';
469
 
470
    ELSIF clk'event AND clk = '1' THEN  -- rising clock edge
471
      IF (DC = '1') THEN
472
        QP_active     <= QP_loaded;
473
        chroma_active <= chroma_loaded;
474
        intra_active  <= intra_loaded;
475
      END IF;
476
 
477
      IF (loadQP = '1') THEN
478
        QP_loaded     <= QP;
479
        chroma_loaded <= chroma;
480
        intra_loaded  <= intra;
481
      END IF;
482
 
483
    END IF;
484
  END PROCESS QP_loader;
485
 
486
 
487
  qcoeff    <= q_result_r;
488
  Q_wr_out  <= out_delay_r(5);          --quantized value is ready after 6
489
                                        --clock cycles
490
  IQ_wr_out <= out_delay_r(6);          --inverse quantized value is ready
491
                                        --after 7 clock cycles
492
 
493
 
494
-- purpose: fetch DCscaler from ROM
495
  DCscaler_from_ROM  : PROCESS (addr_DCscaler_r)
496
    VARIABLE address : integer;
497
  BEGIN
498 176 lanttu
    --address := conv_integer(unsigned(addr_DCscaler_r));
499
    address := 1;                                       -- LM 12.6.2013 changed dcscaler to constant 8
500
        DCscaler <= ROM_DCSCALER(address);
501 145 lanttu
  END PROCESS DCscaler_from_ROM;
502
 
503
-- purpose: fetch Inv_QP from ROM
504
  Inv_QP_from_ROM    : PROCESS (addr_inv_qp_r)
505
    VARIABLE address : integer;
506
  BEGIN
507
    address := conv_integer(unsigned(addr_inv_qp_r));
508
    inv_QP <= ROM_INV_QP(address);
509
  END PROCESS Inv_QP_from_ROM;
510
 
511
-- purpose: fetch Inv_dcscaler from ROM
512
  Inv_DCscaler_from_ROM : PROCESS (addr_inv_dcscaler_r)
513
    VARIABLE address    : integer;
514
  BEGIN
515 176 lanttu
    --address := conv_integer(unsigned(addr_inv_dcscaler_r));
516
    address := 1;                                       -- LM 12.6.2013 changed dcscaler to constant 8
517
        inv_DCscaler <= ROM_INV_DCSCALER(address);
518 145 lanttu
  END PROCESS Inv_DCscaler_from_ROM;
519
 
520
 
521
  -- purpose: datapath for MPEG4 Quantizer
522
  datapath_quantizer        : PROCESS (coeff_in_r, abs_input_r, q_pre_sub_r,
523
                                       q_mul_r, q_clip_r, intra_dc_delay_r,
524
                                       Inv_DCscaler, Inv_QP, sign_delay_r,
525
                                       QP_active,
526
                                       intra_active, quantizer_multiplier_r)
527
    VARIABLE temp_input     : signed(QUANT_inputw_co DOWNTO 0);
528
    VARIABLE pre_subtracted : unsigned(QUANT_inputw_co+1 DOWNTO 0);
529
    VARIABLE pre_subtractor : unsigned(QUANT_inputw_co+1 DOWNTO 0);
530
    VARIABLE pre_sub_result : unsigned(QUANT_inputw_co+1 DOWNTO 0);
531
 
532
    VARIABLE temp_clip   : unsigned(QUANT_resultw_co+2 DOWNTO 0);
533
    VARIABLE temp_result : signed(QUANT_resultw_co-1 DOWNTO 0);
534
    VARIABLE temp_mul    : unsigned(QUANT_inputw_co+qmulw_g DOWNTO 0);
535
  BEGIN  -- PROCESS datapath_quantizer
536
 
537
-------------------------------------------------------------------------------
538
-- PIPELINE STAGE 1
539
-- take absolute value from input, and multiply it by two
540
-------------------------------------------------------------------------------
541
    --sign of input coefficient
542
    sign <= coeff_in_r(QUANT_inputw_co-1);
543
 
544
    temp_input := conv_signed(signed(coeff_in_r), QUANT_inputw_co+1);
545
    --multiply input by 2
546
    temp_input := SHL(temp_input, conv_unsigned(1, 1));
547
    --take absolute value
548
    abs_input <= conv_unsigned(ABS(temp_input), QUANT_inputw_co+1);
549
 
550
-------------------------------------------------------------------------------
551
-- PIPELINE STAGE 2
552
-- if inter frame subtract QP from result of previous stage
553
-- if intra frame, do nothing
554
-------------------------------------------------------------------------------
555
    IF (intra_active = '0') THEN
556
      --if INTER frame, subtract QP from 2*coeff_in
557
      pre_subtractor := conv_unsigned(unsigned(QP_active), QUANT_inputw_co+2);
558
    ELSE
559
      --if INTRA frame, subtract nothing
560
      pre_subtractor := (OTHERS => '0');
561
    END IF;
562
 
563
    --add one bit to left
564
    pre_subtracted := conv_unsigned(abs_input_r, QUANT_inputw_co+2);
565
    pre_sub_result := pre_subtracted - pre_subtractor;
566
 
567
    IF (pre_sub_result(QUANT_inputw_co+1) = '1') THEN
568
      --if pre_subtracted < pre_subtractor
569
      q_pre_sub <= (OTHERS => '0');
570
    ELSE
571
      q_pre_sub <= pre_sub_result(QUANT_inputw_co DOWNTO 0);
572
    END IF;
573
 
574
 
575
 
576
-------------------------------------------------------------------------------
577
-- PIPELINE STAGE 3
578
-- multiply result from previous stage with inverse of QP or DCscaler
579
-------------------------------------------------------------------------------
580
 
581
    --choose quantizer_multiplier
582
    IF (intra_dc_delay_r(0) = '1') THEN
583
      quantizer_multiplier <= Inv_DCscaler;
584
    ELSE
585
      quantizer_multiplier <= Inv_QP;
586
    END IF;
587
 
588
    temp_mul := quantizer_multiplier_r * q_pre_sub_r;
589
    --remove fraction point, and divide by two
590
    temp_mul := SHR(temp_mul, conv_unsigned(qmulw_g+1, 5));
591
    q_mul <= temp_mul(QUANT_resultw_co+2 DOWNTO 0);
592
 
593
-------------------------------------------------------------------------------
594
-- PIPELINE STAGE 4
595
-- Clip result to specified range
596
-------------------------------------------------------------------------------
597
    temp_clip := q_mul_r;
598
 
599
    IF (intra_dc_delay_r(2) = '1') THEN
600
      --round
601
      temp_clip := temp_clip + conv_unsigned(1, QUANT_resultw_co+3);
602
      temp_clip := SHR(temp_clip, conv_unsigned(1, 1));
603
 
604
      IF (temp_clip > 254) THEN
605
        q_clip <= conv_unsigned(254, QUANT_resultw_co);
606
      ELSIF (temp_clip = 0) THEN
607
        q_clip <= conv_unsigned(1, QUANT_resultw_co);
608
      ELSE
609
        q_clip <= conv_unsigned(temp_clip(QUANT_resultw_co-1 DOWNTO 0),
610
                                QUANT_resultw_co);
611
      END IF;
612
 
613
    ELSE
614
      --truncate instead of round
615
      temp_clip := SHR(temp_clip, conv_unsigned(1, 1));
616
      IF (temp_clip > 127) THEN
617
        q_clip <= conv_unsigned(127, QUANT_resultw_co);
618
      ELSE
619
        q_clip <= conv_unsigned(temp_clip(QUANT_resultw_co-1 DOWNTO 0),
620
                                QUANT_resultw_co);
621
      END IF;
622
    END IF;
623
 
624
-------------------------------------------------------------------------------
625
-- PIPELINE STAGE 5
626
-- multiply result from previous stage with sign(coeff_in)
627
-- check, if quantizer result is zero (and save this information)
628
-------------------------------------------------------------------------------
629
    IF (sign_delay_r(3) = '0') THEN     --positive
630
      q_result <= conv_std_logic_vector(q_clip_r, QUANT_resultw_co);
631
    ELSE
632
      --negative
633
      temp_result := signed(q_clip_r);
634
      temp_result := -temp_result;
635
      q_result <= conv_std_logic_vector(temp_result, QUANT_resultw_co);
636
    END IF;
637
 
638
    IF (q_clip_r = 0) THEN
639
      zero_quant <= '1';
640
    ELSE
641
      zero_quant <= '0';
642
    END IF;
643
  END PROCESS datapath_quantizer;
644
 
645
------------------------------------------------------------------------------
646
------------------------------------------------------------------------------
647
------------------------------------------------------------------------------
648
------------------------------------------------------------------------------
649
 
650
  -- purpose: datapath for MPEG4 Inverse Quantizer
651
  datapath_invquantizer : PROCESS (q_clip_r, iq_mul_r, iq_post_sub_r,
652
                                   QP_active,
653
                                   intra_dc_delay_r, DCscaler, r_zero_delay_r,
654
                                   sign_delay_r, invquant_multiplier_r)
655
 
656
    VARIABLE temp_pre_add    : unsigned(QUANT_resultw_co DOWNTO 0);
657
    VARIABLE temp_mul        : unsigned(QUANT_resultw_co+6 DOWNTO 0);
658
    VARIABLE temp_subtractor : unsigned(IQUANT_resultw_co-1 DOWNTO 0);
659
    VARIABLE temp_output     : signed(IQUANT_resultw_co-1 DOWNTO 0);
660
  BEGIN  -- PROCESS datapath_invquantizer
661
-------------------------------------------------------------------------------
662
-- PIPELINE STAGE 1
663
-- Multiply input by 2.
664
-- If not INTRA-DC coefficient, add +1 to input,
665
-- Multiply with QP or DCscaler
666
-------------------------------------------------------------------------------
667
    temp_pre_add(QUANT_resultw_co DOWNTO 1) := q_clip_r;
668
    temp_pre_add(0)                         := NOT(intra_dc_delay_r(3));
669
 
670
--choose multiplier
671
    IF (intra_dc_delay_r(2) = '1') THEN
672
      invquant_multiplier <= conv_unsigned(DCscaler, 6);
673
    ELSE
674
      invquant_multiplier <= conv_unsigned(unsigned(QP_active), 6);
675
    END IF;
676
 
677
    temp_mul := invquant_multiplier_r * temp_pre_add;
678
    iq_mul <= temp_mul(IQUANT_resultw_co DOWNTO 0);
679
 
680
-------------------------------------------------------------------------------
681
-- PIPELINE STAGE 2
682
-- If QP is even, subtract by one
683
-------------------------------------------------------------------------------
684
    IF (intra_dc_delay_r(4) = '1') THEN
685
      --IF INTRA-DC coefficient divide by 2
686
      iq_post_sub <= iq_mul_r(IQUANT_resultw_co DOWNTO 1);
687
    ELSE
688
      --subtract one, if QP is even
689
      temp_subtractor    := (OTHERS => '0');
690
      temp_subtractor(0) := NOT QP_active(0);
691
      iq_post_sub <= iq_mul_r(IQUANT_resultw_co-1 DOWNTO 0)-temp_subtractor;
692
    END IF;
693
 
694
-------------------------------------------------------------------------------
695
-- PIPELINE STAGE 3
696
-- Multiply result with sign.
697
-------------------------------------------------------------------------------
698
    IF (r_zero_delay_r(1) = '1') THEN
699
      --if quantized value was zero, inverse quantized value must also be zero
700
      rcoeff   <= (OTHERS => '0');
701
    ELSE
702
      IF (sign_delay_r(5) = '0') THEN
703
        --positive
704
        rcoeff <= conv_std_logic_vector(iq_post_sub_r, IQUANT_resultw_co);
705
      ELSE
706
        --negative
707
        temp_output := signed(iq_post_sub_r);
708
        temp_output := -temp_output;
709
        rcoeff <= conv_std_logic_vector(temp_output, IQUANT_resultw_co);
710
      END IF;
711
    END IF;
712
  END PROCESS datapath_invquantizer;
713
END rtl;
714
 
715
 
716
 

powered by: WebSVN 2.1.0

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