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 |
|
|
|