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 145

Go to most recent revision | 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
    address := conv_integer(unsigned(addr_DCscaler_r));
499
    DCscaler <= ROM_DCSCALER(address);
500
  END PROCESS DCscaler_from_ROM;
501
 
502
-- purpose: fetch Inv_QP from ROM
503
  Inv_QP_from_ROM    : PROCESS (addr_inv_qp_r)
504
    VARIABLE address : integer;
505
  BEGIN
506
    address := conv_integer(unsigned(addr_inv_qp_r));
507
    inv_QP <= ROM_INV_QP(address);
508
  END PROCESS Inv_QP_from_ROM;
509
 
510
-- purpose: fetch Inv_dcscaler from ROM
511
  Inv_DCscaler_from_ROM : PROCESS (addr_inv_dcscaler_r)
512
    VARIABLE address    : integer;
513
  BEGIN
514
    address := conv_integer(unsigned(addr_inv_dcscaler_r));
515
    inv_DCscaler <= ROM_INV_DCSCALER(address);
516
  END PROCESS Inv_DCscaler_from_ROM;
517
 
518
 
519
  -- purpose: datapath for MPEG4 Quantizer
520
  datapath_quantizer        : PROCESS (coeff_in_r, abs_input_r, q_pre_sub_r,
521
                                       q_mul_r, q_clip_r, intra_dc_delay_r,
522
                                       Inv_DCscaler, Inv_QP, sign_delay_r,
523
                                       QP_active,
524
                                       intra_active, quantizer_multiplier_r)
525
    VARIABLE temp_input     : signed(QUANT_inputw_co DOWNTO 0);
526
    VARIABLE pre_subtracted : unsigned(QUANT_inputw_co+1 DOWNTO 0);
527
    VARIABLE pre_subtractor : unsigned(QUANT_inputw_co+1 DOWNTO 0);
528
    VARIABLE pre_sub_result : unsigned(QUANT_inputw_co+1 DOWNTO 0);
529
 
530
    VARIABLE temp_clip   : unsigned(QUANT_resultw_co+2 DOWNTO 0);
531
    VARIABLE temp_result : signed(QUANT_resultw_co-1 DOWNTO 0);
532
    VARIABLE temp_mul    : unsigned(QUANT_inputw_co+qmulw_g DOWNTO 0);
533
  BEGIN  -- PROCESS datapath_quantizer
534
 
535
-------------------------------------------------------------------------------
536
-- PIPELINE STAGE 1
537
-- take absolute value from input, and multiply it by two
538
-------------------------------------------------------------------------------
539
    --sign of input coefficient
540
    sign <= coeff_in_r(QUANT_inputw_co-1);
541
 
542
    temp_input := conv_signed(signed(coeff_in_r), QUANT_inputw_co+1);
543
    --multiply input by 2
544
    temp_input := SHL(temp_input, conv_unsigned(1, 1));
545
    --take absolute value
546
    abs_input <= conv_unsigned(ABS(temp_input), QUANT_inputw_co+1);
547
 
548
-------------------------------------------------------------------------------
549
-- PIPELINE STAGE 2
550
-- if inter frame subtract QP from result of previous stage
551
-- if intra frame, do nothing
552
-------------------------------------------------------------------------------
553
    IF (intra_active = '0') THEN
554
      --if INTER frame, subtract QP from 2*coeff_in
555
      pre_subtractor := conv_unsigned(unsigned(QP_active), QUANT_inputw_co+2);
556
    ELSE
557
      --if INTRA frame, subtract nothing
558
      pre_subtractor := (OTHERS => '0');
559
    END IF;
560
 
561
    --add one bit to left
562
    pre_subtracted := conv_unsigned(abs_input_r, QUANT_inputw_co+2);
563
    pre_sub_result := pre_subtracted - pre_subtractor;
564
 
565
    IF (pre_sub_result(QUANT_inputw_co+1) = '1') THEN
566
      --if pre_subtracted < pre_subtractor
567
      q_pre_sub <= (OTHERS => '0');
568
    ELSE
569
      q_pre_sub <= pre_sub_result(QUANT_inputw_co DOWNTO 0);
570
    END IF;
571
 
572
 
573
 
574
-------------------------------------------------------------------------------
575
-- PIPELINE STAGE 3
576
-- multiply result from previous stage with inverse of QP or DCscaler
577
-------------------------------------------------------------------------------
578
 
579
    --choose quantizer_multiplier
580
    IF (intra_dc_delay_r(0) = '1') THEN
581
      quantizer_multiplier <= Inv_DCscaler;
582
    ELSE
583
      quantizer_multiplier <= Inv_QP;
584
    END IF;
585
 
586
    temp_mul := quantizer_multiplier_r * q_pre_sub_r;
587
    --remove fraction point, and divide by two
588
    temp_mul := SHR(temp_mul, conv_unsigned(qmulw_g+1, 5));
589
    q_mul <= temp_mul(QUANT_resultw_co+2 DOWNTO 0);
590
 
591
-------------------------------------------------------------------------------
592
-- PIPELINE STAGE 4
593
-- Clip result to specified range
594
-------------------------------------------------------------------------------
595
    temp_clip := q_mul_r;
596
 
597
    IF (intra_dc_delay_r(2) = '1') THEN
598
      --round
599
      temp_clip := temp_clip + conv_unsigned(1, QUANT_resultw_co+3);
600
      temp_clip := SHR(temp_clip, conv_unsigned(1, 1));
601
 
602
      IF (temp_clip > 254) THEN
603
        q_clip <= conv_unsigned(254, QUANT_resultw_co);
604
      ELSIF (temp_clip = 0) THEN
605
        q_clip <= conv_unsigned(1, QUANT_resultw_co);
606
      ELSE
607
        q_clip <= conv_unsigned(temp_clip(QUANT_resultw_co-1 DOWNTO 0),
608
                                QUANT_resultw_co);
609
      END IF;
610
 
611
    ELSE
612
      --truncate instead of round
613
      temp_clip := SHR(temp_clip, conv_unsigned(1, 1));
614
      IF (temp_clip > 127) THEN
615
        q_clip <= conv_unsigned(127, QUANT_resultw_co);
616
      ELSE
617
        q_clip <= conv_unsigned(temp_clip(QUANT_resultw_co-1 DOWNTO 0),
618
                                QUANT_resultw_co);
619
      END IF;
620
    END IF;
621
 
622
-------------------------------------------------------------------------------
623
-- PIPELINE STAGE 5
624
-- multiply result from previous stage with sign(coeff_in)
625
-- check, if quantizer result is zero (and save this information)
626
-------------------------------------------------------------------------------
627
    IF (sign_delay_r(3) = '0') THEN     --positive
628
      q_result <= conv_std_logic_vector(q_clip_r, QUANT_resultw_co);
629
    ELSE
630
      --negative
631
      temp_result := signed(q_clip_r);
632
      temp_result := -temp_result;
633
      q_result <= conv_std_logic_vector(temp_result, QUANT_resultw_co);
634
    END IF;
635
 
636
    IF (q_clip_r = 0) THEN
637
      zero_quant <= '1';
638
    ELSE
639
      zero_quant <= '0';
640
    END IF;
641
  END PROCESS datapath_quantizer;
642
 
643
------------------------------------------------------------------------------
644
------------------------------------------------------------------------------
645
------------------------------------------------------------------------------
646
------------------------------------------------------------------------------
647
 
648
  -- purpose: datapath for MPEG4 Inverse Quantizer
649
  datapath_invquantizer : PROCESS (q_clip_r, iq_mul_r, iq_post_sub_r,
650
                                   QP_active,
651
                                   intra_dc_delay_r, DCscaler, r_zero_delay_r,
652
                                   sign_delay_r, invquant_multiplier_r)
653
 
654
    VARIABLE temp_pre_add    : unsigned(QUANT_resultw_co DOWNTO 0);
655
    VARIABLE temp_mul        : unsigned(QUANT_resultw_co+6 DOWNTO 0);
656
    VARIABLE temp_subtractor : unsigned(IQUANT_resultw_co-1 DOWNTO 0);
657
    VARIABLE temp_output     : signed(IQUANT_resultw_co-1 DOWNTO 0);
658
  BEGIN  -- PROCESS datapath_invquantizer
659
-------------------------------------------------------------------------------
660
-- PIPELINE STAGE 1
661
-- Multiply input by 2.
662
-- If not INTRA-DC coefficient, add +1 to input,
663
-- Multiply with QP or DCscaler
664
-------------------------------------------------------------------------------
665
    temp_pre_add(QUANT_resultw_co DOWNTO 1) := q_clip_r;
666
    temp_pre_add(0)                         := NOT(intra_dc_delay_r(3));
667
 
668
--choose multiplier
669
    IF (intra_dc_delay_r(2) = '1') THEN
670
      invquant_multiplier <= conv_unsigned(DCscaler, 6);
671
    ELSE
672
      invquant_multiplier <= conv_unsigned(unsigned(QP_active), 6);
673
    END IF;
674
 
675
    temp_mul := invquant_multiplier_r * temp_pre_add;
676
    iq_mul <= temp_mul(IQUANT_resultw_co DOWNTO 0);
677
 
678
-------------------------------------------------------------------------------
679
-- PIPELINE STAGE 2
680
-- If QP is even, subtract by one
681
-------------------------------------------------------------------------------
682
    IF (intra_dc_delay_r(4) = '1') THEN
683
      --IF INTRA-DC coefficient divide by 2
684
      iq_post_sub <= iq_mul_r(IQUANT_resultw_co DOWNTO 1);
685
    ELSE
686
      --subtract one, if QP is even
687
      temp_subtractor    := (OTHERS => '0');
688
      temp_subtractor(0) := NOT QP_active(0);
689
      iq_post_sub <= iq_mul_r(IQUANT_resultw_co-1 DOWNTO 0)-temp_subtractor;
690
    END IF;
691
 
692
-------------------------------------------------------------------------------
693
-- PIPELINE STAGE 3
694
-- Multiply result with sign.
695
-------------------------------------------------------------------------------
696
    IF (r_zero_delay_r(1) = '1') THEN
697
      --if quantized value was zero, inverse quantized value must also be zero
698
      rcoeff   <= (OTHERS => '0');
699
    ELSE
700
      IF (sign_delay_r(5) = '0') THEN
701
        --positive
702
        rcoeff <= conv_std_logic_vector(iq_post_sub_r, IQUANT_resultw_co);
703
      ELSE
704
        --negative
705
        temp_output := signed(iq_post_sub_r);
706
        temp_output := -temp_output;
707
        rcoeff <= conv_std_logic_vector(temp_output, IQUANT_resultw_co);
708
      END IF;
709
    END IF;
710
  END PROCESS datapath_invquantizer;
711
END rtl;
712
 
713
 
714
 

powered by: WebSVN 2.1.0

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