1 |
3 |
jamey.hick |
//**********************************************************************
|
2 |
|
|
// Inverse Quantizer and Inverse Transformer implementation
|
3 |
|
|
//----------------------------------------------------------------------
|
4 |
|
|
//
|
5 |
|
|
//
|
6 |
|
|
|
7 |
|
|
package mkInverseTrans;
|
8 |
|
|
|
9 |
|
|
import H264Types::*;
|
10 |
|
|
|
11 |
|
|
import IInverseTrans::*;
|
12 |
|
|
import FIFO::*;
|
13 |
|
|
import Vector::*;
|
14 |
|
|
|
15 |
|
|
import Connectable::*;
|
16 |
|
|
import GetPut::*;
|
17 |
|
|
import ClientServer::*;
|
18 |
|
|
|
19 |
|
|
|
20 |
|
|
//-----------------------------------------------------------
|
21 |
|
|
// Local Datatypes
|
22 |
|
|
//-----------------------------------------------------------
|
23 |
|
|
|
24 |
|
|
typedef union tagged
|
25 |
|
|
{
|
26 |
|
|
void Start; //not working on anything in particular
|
27 |
|
|
void Intra16x16DC;
|
28 |
|
|
void Intra16x16;
|
29 |
|
|
void ChromaDC;
|
30 |
|
|
void Chroma;
|
31 |
|
|
void Regular4x4;
|
32 |
|
|
}
|
33 |
|
|
State deriving(Eq,Bits);
|
34 |
|
|
|
35 |
|
|
typedef union tagged
|
36 |
|
|
{
|
37 |
|
|
// void Initializing; //not working on anything in particular
|
38 |
|
|
void Passing; //not working on anything in particular
|
39 |
|
|
void LoadingDC;
|
40 |
|
|
void Scaling; //does not include scaling for DC (just loading in that case)
|
41 |
|
|
void Transforming;
|
42 |
|
|
void ScalingDC;
|
43 |
|
|
void Outputing;
|
44 |
|
|
}
|
45 |
|
|
Process deriving(Eq,Bits);
|
46 |
|
|
|
47 |
|
|
|
48 |
|
|
//-----------------------------------------------------------
|
49 |
|
|
// Helper functions
|
50 |
|
|
|
51 |
|
|
function Bit#(6) qpi_to_qpc( Bit#(6) qpi );//mapping from qpi to qpc
|
52 |
|
|
case ( qpi )
|
53 |
|
|
30: return 29;
|
54 |
|
|
31: return 30;
|
55 |
|
|
32: return 31;
|
56 |
|
|
33: return 32;
|
57 |
|
|
34: return 32;
|
58 |
|
|
35: return 33;
|
59 |
|
|
36: return 34;
|
60 |
|
|
37: return 34;
|
61 |
|
|
38: return 35;
|
62 |
|
|
39: return 35;
|
63 |
|
|
40: return 36;
|
64 |
|
|
41: return 36;
|
65 |
|
|
42: return 37;
|
66 |
|
|
43: return 37;
|
67 |
|
|
44: return 37;
|
68 |
|
|
45: return 38;
|
69 |
|
|
46: return 38;
|
70 |
|
|
47: return 38;
|
71 |
|
|
48: return 39;
|
72 |
|
|
49: return 39;
|
73 |
|
|
50: return 39;
|
74 |
|
|
51: return 39;
|
75 |
|
|
default: return qpi;
|
76 |
|
|
endcase
|
77 |
|
|
endfunction
|
78 |
|
|
|
79 |
|
|
|
80 |
|
|
function Bit#(4) reverseInverseZigZagScan( Bit#(4) idx );
|
81 |
|
|
case ( idx )
|
82 |
|
|
0: return 15;
|
83 |
|
|
1: return 14;
|
84 |
|
|
2: return 11;
|
85 |
|
|
3: return 7;
|
86 |
|
|
4: return 10;
|
87 |
|
|
5: return 13;
|
88 |
|
|
6: return 12;
|
89 |
|
|
7: return 9;
|
90 |
|
|
8: return 6;
|
91 |
|
|
9: return 3;
|
92 |
|
|
10: return 2;
|
93 |
|
|
11: return 5;
|
94 |
|
|
12: return 8;
|
95 |
|
|
13: return 4;
|
96 |
|
|
14: return 1;
|
97 |
|
|
15: return 0;
|
98 |
|
|
endcase
|
99 |
|
|
endfunction
|
100 |
|
|
|
101 |
|
|
|
102 |
|
|
function Tuple2#(Bit#(4),Bit#(3)) qpdivmod6( Bit#(6) qp );
|
103 |
|
|
Bit#(6) tempqp = qp;
|
104 |
|
|
Bit#(4) tempdiv = 0;
|
105 |
|
|
for(Integer ii=5; ii>=2; ii=ii-1)
|
106 |
|
|
begin
|
107 |
|
|
if(tempqp >= (6'b000011 << (fromInteger(ii)-1)))
|
108 |
|
|
begin
|
109 |
|
|
tempqp = tempqp - (6'b000011 << (fromInteger(ii)-1));
|
110 |
|
|
tempdiv = tempdiv | (4'b0001 << (fromInteger(ii)-2));
|
111 |
|
|
end
|
112 |
|
|
end
|
113 |
|
|
return tuple2(tempdiv,truncate(tempqp));
|
114 |
|
|
endfunction
|
115 |
|
|
|
116 |
|
|
|
117 |
|
|
function Vector#(4,Bit#(16)) dcTransFunc( Bit#(16) in0, Bit#(16) in1, Bit#(16) in2, Bit#(16) in3 );
|
118 |
|
|
Vector#(4,Bit#(16)) resultVector = replicate(0);
|
119 |
|
|
resultVector[0] = in0 + in1 + in2 + in3;
|
120 |
|
|
resultVector[1] = in0 + in1 - in2 - in3;
|
121 |
|
|
resultVector[2] = in0 - in1 - in2 + in3;
|
122 |
|
|
resultVector[3] = in0 - in1 + in2 - in3;
|
123 |
|
|
return resultVector;
|
124 |
|
|
endfunction
|
125 |
|
|
|
126 |
|
|
|
127 |
|
|
function Vector#(4,Bit#(16)) transFunc( Bit#(16) in0, Bit#(16) in1, Bit#(16) in2, Bit#(16) in3 );
|
128 |
|
|
Vector#(4,Bit#(16)) resultVector = replicate(0);
|
129 |
|
|
Bit#(16) workValue0 = in0 + in2;
|
130 |
|
|
Bit#(16) workValue1 = in0 - in2;
|
131 |
|
|
Bit#(16) workValue2 = signedShiftRight(in1,1) - in3;
|
132 |
|
|
Bit#(16) workValue3 = in1 + signedShiftRight(in3,1);
|
133 |
|
|
resultVector[0] = workValue0 + workValue3;
|
134 |
|
|
resultVector[1] = workValue1 + workValue2;
|
135 |
|
|
resultVector[2] = workValue1 - workValue2;
|
136 |
|
|
resultVector[3] = workValue0 - workValue3;
|
137 |
|
|
return resultVector;
|
138 |
|
|
endfunction
|
139 |
|
|
|
140 |
|
|
|
141 |
|
|
//-----------------------------------------------------------
|
142 |
|
|
// Inverse Quantizer and Inverse Transformer Module
|
143 |
|
|
//-----------------------------------------------------------
|
144 |
|
|
|
145 |
|
|
|
146 |
|
|
(* synthesize *)
|
147 |
|
|
module mkInverseTrans( IInverseTrans );
|
148 |
|
|
|
149 |
|
|
FIFO#(EntropyDecOT_InverseTrans) infifo <- mkSizedFIFO(inverseTrans_infifo_size);
|
150 |
|
|
FIFO#(InverseTransOT) outfifo <- mkFIFO;
|
151 |
|
|
Reg#(Bit#(4)) blockNum <- mkReg(0);
|
152 |
|
|
Reg#(Bit#(4)) pixelNum <- mkReg(0);//also used as a regular counter during inverse transformation
|
153 |
|
|
Reg#(State) state <- mkReg(Start);
|
154 |
|
|
Reg#(Process) process <- mkReg(Passing);
|
155 |
|
|
|
156 |
|
|
Reg#(Bit#(5)) chroma_qp_index_offset <- mkReg(0);
|
157 |
|
|
Reg#(Bit#(6)) ppspic_init_qp <- mkReg(0);
|
158 |
|
|
Reg#(Bit#(6)) slice_qp <- mkReg(0);
|
159 |
|
|
Reg#(Bit#(6)) qpy <- mkReg(0);//Calculating it requires 8 bits, but value only 0 to 51
|
160 |
|
|
Reg#(Bit#(6)) qpc <- mkReg(0);
|
161 |
|
|
Reg#(Bit#(3)) qpymod6 <- mkReg(0);
|
162 |
|
|
Reg#(Bit#(3)) qpcmod6 <- mkReg(0);
|
163 |
|
|
Reg#(Bit#(4)) qpydiv6 <- mkReg(0);
|
164 |
|
|
Reg#(Bit#(4)) qpcdiv6 <- mkReg(0);
|
165 |
|
|
|
166 |
|
|
Reg#(Vector#(16,Bit#(16))) workVector <- mkRegU();
|
167 |
|
|
Reg#(Vector#(16,Bit#(16))) storeVector <- mkRegU();
|
168 |
|
|
|
169 |
|
|
|
170 |
|
|
|
171 |
|
|
//-----------------------------------------------------------
|
172 |
|
|
// Rules
|
173 |
|
|
|
174 |
|
|
|
175 |
|
|
rule passing (process matches Passing);
|
176 |
|
|
//$display( "Trace Inverse Trans: passing infifo packed %h", pack(infifo.first()));
|
177 |
|
|
case (infifo.first()) matches
|
178 |
|
|
tagged NewUnit . xdata :
|
179 |
|
|
begin
|
180 |
|
|
infifo.deq();
|
181 |
|
|
$display("ccl3newunit");
|
182 |
|
|
$display("ccl3rbspbyte %h", xdata);
|
183 |
|
|
end
|
184 |
|
|
tagged SDMmbtype .xdata :
|
185 |
|
|
begin
|
186 |
|
|
infifo.deq();
|
187 |
|
|
$display( "INFO InverseTrans: SDMmbtype %0d", xdata);
|
188 |
|
|
if(mbPartPredMode(xdata,0) == Intra_16x16)
|
189 |
|
|
state <= Intra16x16DC;
|
190 |
|
|
else
|
191 |
|
|
state <= Regular4x4;
|
192 |
|
|
end
|
193 |
|
|
tagged PPSpic_init_qp .xdata :
|
194 |
|
|
begin
|
195 |
|
|
infifo.deq();
|
196 |
|
|
ppspic_init_qp <= truncate(xdata);
|
197 |
|
|
end
|
198 |
|
|
tagged SHslice_qp_delta .xdata :
|
199 |
|
|
begin
|
200 |
|
|
infifo.deq();
|
201 |
|
|
slice_qp <= ppspic_init_qp+truncate(xdata);
|
202 |
|
|
Bit#(6) qpynext = ppspic_init_qp+truncate(xdata);
|
203 |
|
|
qpy <= qpynext;
|
204 |
|
|
Bit#(7) qpitemp = zeroExtend(chroma_qp_index_offset+12) + zeroExtend(qpynext);
|
205 |
|
|
Bit#(6) qpi;
|
206 |
|
|
if(qpitemp < 12)
|
207 |
|
|
qpi = 0;
|
208 |
|
|
else if(qpitemp > 63)
|
209 |
|
|
qpi = 51;
|
210 |
|
|
else
|
211 |
|
|
qpi = truncate(qpitemp-12);
|
212 |
|
|
qpc <= qpi_to_qpc(qpi);
|
213 |
|
|
outfifo.enq(IBTmb_qp {qpy:qpynext,qpc:qpi_to_qpc(qpi)});
|
214 |
|
|
end
|
215 |
|
|
tagged SDMmb_qp_delta .xdata :
|
216 |
|
|
begin
|
217 |
|
|
infifo.deq();
|
218 |
|
|
Bit#(8) qpytemp = zeroExtend(qpy) + zeroExtend(xdata+52);
|
219 |
|
|
Bit#(6) qpynext;
|
220 |
|
|
if(qpytemp >= 104)
|
221 |
|
|
qpynext = truncate(qpytemp - 104);
|
222 |
|
|
else if(qpytemp >= 52)
|
223 |
|
|
qpynext = truncate(qpytemp - 52);
|
224 |
|
|
else
|
225 |
|
|
qpynext = truncate(qpytemp);
|
226 |
|
|
qpy <= qpynext;
|
227 |
|
|
|
228 |
|
|
//$display( "TRACE InverseTrans: qpy %0d", qpynext );
|
229 |
|
|
//$display( "TRACE InverseTrans: qpy %0d", qpynext );
|
230 |
|
|
Tuple2#(Bit#(4),Bit#(3)) temptuple = qpdivmod6(qpynext);
|
231 |
|
|
qpydiv6 <= tpl_1(temptuple);
|
232 |
|
|
qpymod6 <= tpl_2(temptuple);
|
233 |
|
|
//$display( "TRACE InverseTrans: qpydiv6 %0d", tpl_1(temptuple) );
|
234 |
|
|
//$display( "TRACE InverseTrans: qpymod6 %0d", tpl_2(temptuple) );
|
235 |
|
|
|
236 |
|
|
Bit#(7) qpitemp = zeroExtend(chroma_qp_index_offset+12) + zeroExtend(qpynext);
|
237 |
|
|
Bit#(6) qpi;
|
238 |
|
|
if(qpitemp < 12)
|
239 |
|
|
qpi = 0;
|
240 |
|
|
else if(qpitemp > 63)
|
241 |
|
|
qpi = 51;
|
242 |
|
|
else
|
243 |
|
|
qpi = truncate(qpitemp-12);
|
244 |
|
|
qpc <= qpi_to_qpc(qpi);
|
245 |
|
|
outfifo.enq(IBTmb_qp {qpy:qpynext,qpc:qpi_to_qpc(qpi)});
|
246 |
|
|
end
|
247 |
|
|
tagged PPSchroma_qp_index_offset .xdata :
|
248 |
|
|
begin
|
249 |
|
|
infifo.deq();
|
250 |
|
|
chroma_qp_index_offset <= xdata;
|
251 |
|
|
end
|
252 |
|
|
tagged SDMRcoeffLevel .xdata :
|
253 |
|
|
begin
|
254 |
|
|
blockNum <= 0;
|
255 |
|
|
pixelNum <= 0;
|
256 |
|
|
if(state == Intra16x16DC)
|
257 |
|
|
begin
|
258 |
|
|
$display( "INFO InverseTrans: 16x16 MB" );
|
259 |
|
|
process <= LoadingDC;
|
260 |
|
|
end
|
261 |
|
|
else
|
262 |
|
|
begin
|
263 |
|
|
$display( "INFO InverseTrans: Non-16x16 MB" );
|
264 |
|
|
process <= Scaling;
|
265 |
|
|
end
|
266 |
|
|
workVector <= replicate(0);
|
267 |
|
|
Tuple2#(Bit#(4),Bit#(3)) temptuple = qpdivmod6(qpc);
|
268 |
|
|
qpcdiv6 <= tpl_1(temptuple);
|
269 |
|
|
qpcmod6 <= tpl_2(temptuple);
|
270 |
|
|
end
|
271 |
|
|
tagged SDMRcoeffLevelZeros .xdata :
|
272 |
|
|
begin
|
273 |
|
|
blockNum <= 0;
|
274 |
|
|
pixelNum <= 0;
|
275 |
|
|
if(state == Intra16x16DC)
|
276 |
|
|
begin
|
277 |
|
|
$display( "INFO InverseTrans: 16x16 MB" );
|
278 |
|
|
process <= LoadingDC;
|
279 |
|
|
end
|
280 |
|
|
else
|
281 |
|
|
begin
|
282 |
|
|
$display( "INFO InverseTrans: Non-16x16 MB" );
|
283 |
|
|
process <= Scaling;
|
284 |
|
|
end
|
285 |
|
|
workVector <= replicate(0);
|
286 |
|
|
Tuple2#(Bit#(4),Bit#(3)) temptuple = qpdivmod6(qpc);
|
287 |
|
|
qpcdiv6 <= tpl_1(temptuple);
|
288 |
|
|
qpcmod6 <= tpl_2(temptuple);
|
289 |
|
|
end
|
290 |
|
|
default: infifo.deq();
|
291 |
|
|
endcase
|
292 |
|
|
endrule
|
293 |
|
|
|
294 |
|
|
|
295 |
|
|
rule loadingDC (process matches LoadingDC);
|
296 |
|
|
Vector#(16,Bit#(16)) workVectorTemp = workVector;
|
297 |
|
|
|
298 |
|
|
case (infifo.first()) matches
|
299 |
|
|
tagged SDMRcoeffLevelZeros .xdata :
|
300 |
|
|
begin
|
301 |
|
|
infifo.deq();
|
302 |
|
|
pixelNum <= pixelNum+truncate(xdata);
|
303 |
|
|
if((state==ChromaDC && zeroExtend(pixelNum)+xdata==8) || zeroExtend(pixelNum)+xdata==16)
|
304 |
|
|
process <= Transforming;
|
305 |
|
|
else if((state==ChromaDC && zeroExtend(pixelNum)+xdata>8) || zeroExtend(pixelNum)+xdata>16)
|
306 |
|
|
$display( "ERROR InverseTrans: loadingDC index overflow" );
|
307 |
|
|
end
|
308 |
|
|
tagged SDMRcoeffLevel .xdata :
|
309 |
|
|
begin
|
310 |
|
|
infifo.deq();
|
311 |
|
|
Bit#(16) workValue = signExtend(xdata);
|
312 |
|
|
if(state==ChromaDC)
|
313 |
|
|
begin
|
314 |
|
|
if(pixelNum<4)
|
315 |
|
|
workVector <= update(workVectorTemp, 3-pixelNum, workValue);
|
316 |
|
|
else
|
317 |
|
|
workVector <= update(workVectorTemp, 11-pixelNum, workValue);
|
318 |
|
|
end
|
319 |
|
|
else
|
320 |
|
|
workVector <= update(workVectorTemp, reverseInverseZigZagScan(pixelNum), workValue);
|
321 |
|
|
pixelNum <= pixelNum+1;
|
322 |
|
|
if((state==ChromaDC && pixelNum==7) || pixelNum==15)
|
323 |
|
|
process <= Transforming;
|
324 |
|
|
else if((state==ChromaDC && pixelNum>7) || pixelNum>15)
|
325 |
|
|
$display( "ERROR InverseTrans: loadingDC index overflow" );
|
326 |
|
|
end
|
327 |
|
|
default: process <= Passing;
|
328 |
|
|
endcase
|
329 |
|
|
endrule
|
330 |
|
|
|
331 |
|
|
|
332 |
|
|
rule scaling (process matches Scaling);
|
333 |
|
|
Vector#(16,Bit#(16)) workVectorTemp = workVector;
|
334 |
|
|
Vector#(16,Bit#(16)) storeVectorTemp = storeVector;
|
335 |
|
|
|
336 |
|
|
case (infifo.first()) matches
|
337 |
|
|
tagged SDMRcoeffLevelZeros .xdata :
|
338 |
|
|
begin
|
339 |
|
|
infifo.deq();
|
340 |
|
|
if(zeroExtend(pixelNum)+xdata==16 || (zeroExtend(pixelNum)+xdata==15 && (state==Chroma || state==Intra16x16)))
|
341 |
|
|
begin
|
342 |
|
|
Bit#(16) prevValue0=0;
|
343 |
|
|
if(state==Intra16x16)
|
344 |
|
|
prevValue0 = select(storeVectorTemp, {blockNum[3],blockNum[1],blockNum[2],blockNum[0]});
|
345 |
|
|
else if(state==Chroma)
|
346 |
|
|
prevValue0 = select(storeVectorTemp, blockNum);
|
347 |
|
|
if(xdata==16 || (xdata==15 && (state==Chroma || state==Intra16x16) && prevValue0==0))
|
348 |
|
|
begin
|
349 |
|
|
outfifo.enq(ITBcoeffLevelZeros);
|
350 |
|
|
////$display("ccl3IBTresidualZeros %0d", 16);
|
351 |
|
|
workVector <= replicate(0);
|
352 |
|
|
if(state==Chroma)
|
353 |
|
|
begin
|
354 |
|
|
if(blockNum<7)
|
355 |
|
|
blockNum <= blockNum+1;
|
356 |
|
|
else if (blockNum==7)
|
357 |
|
|
begin
|
358 |
|
|
blockNum <= 0;
|
359 |
|
|
process <= Passing;
|
360 |
|
|
end
|
361 |
|
|
else
|
362 |
|
|
$display( "ERROR InverseTrans: scaling outputing chroma unexpected blockNum" );
|
363 |
|
|
end
|
364 |
|
|
else
|
365 |
|
|
begin
|
366 |
|
|
blockNum <= blockNum+1;
|
367 |
|
|
if(blockNum==15)
|
368 |
|
|
begin
|
369 |
|
|
state <= ChromaDC;
|
370 |
|
|
process <= LoadingDC;
|
371 |
|
|
end
|
372 |
|
|
end
|
373 |
|
|
end
|
374 |
|
|
else
|
375 |
|
|
process <= Transforming;
|
376 |
|
|
pixelNum <= 0;
|
377 |
|
|
end
|
378 |
|
|
else if(zeroExtend(pixelNum)+xdata>16 || (zeroExtend(pixelNum)+xdata>15 && (state==Chroma || state==Intra16x16)))
|
379 |
|
|
$display( "ERROR InverseTrans: scaling index overflow" );
|
380 |
|
|
else
|
381 |
|
|
pixelNum <= pixelNum+truncate(xdata);
|
382 |
|
|
//$display( "TRACE InverseTrans: coeff zeros %0d", xdata );
|
383 |
|
|
end
|
384 |
|
|
tagged SDMRcoeffLevel .xdata :
|
385 |
|
|
begin
|
386 |
|
|
infifo.deq();
|
387 |
|
|
Bit#(6) qp;
|
388 |
|
|
Bit#(4) qpdiv6;
|
389 |
|
|
Bit#(3) qpmod6;
|
390 |
|
|
if(state==Chroma)
|
391 |
|
|
begin
|
392 |
|
|
qp = qpc;
|
393 |
|
|
qpdiv6 = qpcdiv6;
|
394 |
|
|
qpmod6 = qpcmod6;
|
395 |
|
|
end
|
396 |
|
|
else
|
397 |
|
|
begin
|
398 |
|
|
qp = qpy;
|
399 |
|
|
qpdiv6 = qpydiv6;
|
400 |
|
|
qpmod6 = qpymod6;
|
401 |
|
|
end
|
402 |
|
|
Bit#(5) levelScaleValue=0;
|
403 |
|
|
if(pixelNum==15 || pixelNum==12 || pixelNum==10 || pixelNum==4)
|
404 |
|
|
begin
|
405 |
|
|
case(qpmod6)
|
406 |
|
|
0: levelScaleValue = 10;
|
407 |
|
|
1: levelScaleValue = 11;
|
408 |
|
|
2: levelScaleValue = 13;
|
409 |
|
|
3: levelScaleValue = 14;
|
410 |
|
|
4: levelScaleValue = 16;
|
411 |
|
|
5: levelScaleValue = 18;
|
412 |
|
|
default: $display( "ERROR InverseTrans: levelScaleGen case default" );
|
413 |
|
|
endcase
|
414 |
|
|
end
|
415 |
|
|
else if(pixelNum==11 || pixelNum==5 || pixelNum==3 || pixelNum==0)
|
416 |
|
|
begin
|
417 |
|
|
case(qpmod6)
|
418 |
|
|
0: levelScaleValue = 16;
|
419 |
|
|
1: levelScaleValue = 18;
|
420 |
|
|
2: levelScaleValue = 20;
|
421 |
|
|
3: levelScaleValue = 23;
|
422 |
|
|
4: levelScaleValue = 25;
|
423 |
|
|
5: levelScaleValue = 29;
|
424 |
|
|
default: $display( "ERROR InverseTrans: levelScaleGen case default" );
|
425 |
|
|
endcase
|
426 |
|
|
end
|
427 |
|
|
else
|
428 |
|
|
begin
|
429 |
|
|
case(qpmod6)
|
430 |
|
|
0: levelScaleValue = 13;
|
431 |
|
|
1: levelScaleValue = 14;
|
432 |
|
|
2: levelScaleValue = 16;
|
433 |
|
|
3: levelScaleValue = 18;
|
434 |
|
|
4: levelScaleValue = 20;
|
435 |
|
|
5: levelScaleValue = 23;
|
436 |
|
|
default: $display( "ERROR InverseTrans: levelScaleGen case default" );
|
437 |
|
|
endcase
|
438 |
|
|
end
|
439 |
|
|
Bit#(16) workValueTemp = zeroExtend(levelScaleValue)*signExtend(xdata);
|
440 |
|
|
Bit#(16) workValue;
|
441 |
|
|
workValue = workValueTemp << zeroExtend(qpdiv6);
|
442 |
|
|
workVector <= update(workVectorTemp, reverseInverseZigZagScan(pixelNum), workValue);
|
443 |
|
|
if(pixelNum==15 || (pixelNum==14 && (state==Chroma || state==Intra16x16)))
|
444 |
|
|
begin
|
445 |
|
|
process <= Transforming;
|
446 |
|
|
pixelNum <= 0;
|
447 |
|
|
end
|
448 |
|
|
else
|
449 |
|
|
pixelNum <= pixelNum+1;
|
450 |
|
|
end
|
451 |
|
|
default: process <= Passing;
|
452 |
|
|
endcase
|
453 |
|
|
endrule
|
454 |
|
|
|
455 |
|
|
|
456 |
|
|
rule transforming (process matches Transforming);
|
457 |
|
|
Vector#(16,Bit#(16)) workVectorTemp = workVector;
|
458 |
|
|
Vector#(16,Bit#(16)) workVectorNew = workVector;
|
459 |
|
|
Vector#(16,Bit#(16)) storeVectorTemp = storeVector;
|
460 |
|
|
|
461 |
|
|
if(state == ChromaDC)
|
462 |
|
|
begin
|
463 |
|
|
case ( pixelNum )
|
464 |
|
|
8:
|
465 |
|
|
begin
|
466 |
|
|
workVectorNew[0] = workVectorTemp[0] + workVectorTemp[2];
|
467 |
|
|
workVectorNew[1] = workVectorTemp[1] + workVectorTemp[3];
|
468 |
|
|
workVectorNew[2] = workVectorTemp[0] - workVectorTemp[2];
|
469 |
|
|
workVectorNew[3] = workVectorTemp[1] - workVectorTemp[3];
|
470 |
|
|
pixelNum <= pixelNum+1;
|
471 |
|
|
end
|
472 |
|
|
9:
|
473 |
|
|
begin
|
474 |
|
|
workVectorNew[0] = workVectorTemp[0] + workVectorTemp[1];
|
475 |
|
|
workVectorNew[1] = workVectorTemp[0] - workVectorTemp[1];
|
476 |
|
|
workVectorNew[2] = workVectorTemp[2] + workVectorTemp[3];
|
477 |
|
|
workVectorNew[3] = workVectorTemp[2] - workVectorTemp[3];
|
478 |
|
|
pixelNum <= pixelNum+1;
|
479 |
|
|
end
|
480 |
|
|
10:
|
481 |
|
|
begin
|
482 |
|
|
workVectorNew[4] = workVectorTemp[4] + workVectorTemp[6];
|
483 |
|
|
workVectorNew[5] = workVectorTemp[5] + workVectorTemp[7];
|
484 |
|
|
workVectorNew[6] = workVectorTemp[4] - workVectorTemp[6];
|
485 |
|
|
workVectorNew[7] = workVectorTemp[5] - workVectorTemp[7];
|
486 |
|
|
pixelNum <= pixelNum+1;
|
487 |
|
|
end
|
488 |
|
|
11:
|
489 |
|
|
begin
|
490 |
|
|
workVectorNew[4] = workVectorTemp[4] + workVectorTemp[5];
|
491 |
|
|
workVectorNew[5] = workVectorTemp[4] - workVectorTemp[5];
|
492 |
|
|
workVectorNew[6] = workVectorTemp[6] + workVectorTemp[7];
|
493 |
|
|
workVectorNew[7] = workVectorTemp[6] - workVectorTemp[7];
|
494 |
|
|
pixelNum <= 0;
|
495 |
|
|
process <= ScalingDC;
|
496 |
|
|
end
|
497 |
|
|
default:
|
498 |
|
|
$display( "ERROR InverseTrans: transforming ChromaDC unexpected pixelNum" );
|
499 |
|
|
endcase
|
500 |
|
|
workVector <= workVectorNew;
|
501 |
|
|
end
|
502 |
|
|
else if(state == Intra16x16DC)
|
503 |
|
|
begin
|
504 |
|
|
Vector#(4,Bit#(16)) resultVector = replicate(0);
|
505 |
|
|
if(pixelNum < 4)
|
506 |
|
|
begin
|
507 |
|
|
Bit#(4) tempIndex = zeroExtend(pixelNum[1:0]);
|
508 |
|
|
resultVector = dcTransFunc( workVectorTemp[tempIndex], workVectorTemp[tempIndex+4], workVectorTemp[tempIndex+8], workVectorTemp[tempIndex+12] );
|
509 |
|
|
for(Integer ii=0; ii<4; ii=ii+1)
|
510 |
|
|
workVectorNew[tempIndex+fromInteger(ii*4)] = resultVector[ii];
|
511 |
|
|
end
|
512 |
|
|
else if(pixelNum < 8)
|
513 |
|
|
begin
|
514 |
|
|
Bit#(4) tempIndex = {pixelNum[1:0],2'b00};
|
515 |
|
|
resultVector = dcTransFunc( workVectorTemp[tempIndex], workVectorTemp[tempIndex+1], workVectorTemp[tempIndex+2], workVectorTemp[tempIndex+3] );
|
516 |
|
|
for(Integer ii=0; ii<4; ii=ii+1)
|
517 |
|
|
workVectorNew[tempIndex+fromInteger(ii)] = resultVector[ii];
|
518 |
|
|
end
|
519 |
|
|
else
|
520 |
|
|
$display( "ERROR InverseTrans: transforming Intra16x16DC unexpected pixelNum" );
|
521 |
|
|
workVector <= workVectorNew;
|
522 |
|
|
if(pixelNum == 7)
|
523 |
|
|
begin
|
524 |
|
|
pixelNum <= 0;
|
525 |
|
|
process <= ScalingDC;
|
526 |
|
|
end
|
527 |
|
|
else
|
528 |
|
|
pixelNum <= pixelNum+1;
|
529 |
|
|
end
|
530 |
|
|
else
|
531 |
|
|
begin
|
532 |
|
|
Vector#(4,Bit#(16)) resultVector = replicate(0);
|
533 |
|
|
if(pixelNum < 4)
|
534 |
|
|
begin
|
535 |
|
|
Bit#(4) tempIndex = {pixelNum[1:0],2'b00};
|
536 |
|
|
Bit#(16) tempValue0 = workVectorTemp[tempIndex];
|
537 |
|
|
if(pixelNum==0)
|
538 |
|
|
begin
|
539 |
|
|
if(state==Intra16x16)
|
540 |
|
|
tempValue0 = select(storeVectorTemp, {blockNum[3],blockNum[1],blockNum[2],blockNum[0]});
|
541 |
|
|
else if(state==Chroma)
|
542 |
|
|
tempValue0 = select(storeVectorTemp, blockNum);
|
543 |
|
|
end
|
544 |
|
|
resultVector = transFunc( tempValue0, workVectorTemp[tempIndex+1], workVectorTemp[tempIndex+2], workVectorTemp[tempIndex+3] );
|
545 |
|
|
for(Integer ii=0; ii<4; ii=ii+1)
|
546 |
|
|
workVectorNew[tempIndex+fromInteger(ii)] = resultVector[ii];
|
547 |
|
|
end
|
548 |
|
|
else if(pixelNum < 8)
|
549 |
|
|
begin
|
550 |
|
|
Bit#(4) tempIndex = zeroExtend(pixelNum[1:0]);
|
551 |
|
|
resultVector = transFunc( workVectorTemp[tempIndex], workVectorTemp[tempIndex+4], workVectorTemp[tempIndex+8], workVectorTemp[tempIndex+12] );
|
552 |
|
|
for(Integer ii=0; ii<4; ii=ii+1)
|
553 |
|
|
workVectorNew[tempIndex+fromInteger(ii*4)] = resultVector[ii];
|
554 |
|
|
end
|
555 |
|
|
else
|
556 |
|
|
$display( "ERROR InverseTrans: transforming regular unexpected pixelNum" );
|
557 |
|
|
workVector <= workVectorNew;
|
558 |
|
|
if(pixelNum == 7)
|
559 |
|
|
begin
|
560 |
|
|
pixelNum <= 0;
|
561 |
|
|
process <= Outputing;
|
562 |
|
|
end
|
563 |
|
|
else
|
564 |
|
|
pixelNum <= pixelNum+1;
|
565 |
|
|
end
|
566 |
|
|
endrule
|
567 |
|
|
|
568 |
|
|
|
569 |
|
|
rule scalingDC (process matches ScalingDC);
|
570 |
|
|
Bit#(6) qp;
|
571 |
|
|
Bit#(4) qpdiv6;
|
572 |
|
|
Bit#(3) qpmod6;
|
573 |
|
|
Bit#(6) workOne = 1;
|
574 |
|
|
Bit#(16) workValue;
|
575 |
|
|
Bit#(22) storeValueTemp;
|
576 |
|
|
Bit#(16) storeValue;
|
577 |
|
|
Vector#(16,Bit#(16)) workVectorTemp = workVector;
|
578 |
|
|
Vector#(16,Bit#(16)) storeVectorTemp = storeVector;
|
579 |
|
|
|
580 |
|
|
if(state==ChromaDC)
|
581 |
|
|
begin
|
582 |
|
|
qp = qpc;
|
583 |
|
|
qpdiv6 = qpcdiv6;
|
584 |
|
|
qpmod6 = qpcmod6;
|
585 |
|
|
end
|
586 |
|
|
else
|
587 |
|
|
begin
|
588 |
|
|
qp = qpy;
|
589 |
|
|
qpdiv6 = qpydiv6;
|
590 |
|
|
qpmod6 = qpymod6;
|
591 |
|
|
end
|
592 |
|
|
workValue = select(workVectorTemp, pixelNum);
|
593 |
|
|
Bit#(5) levelScaleValue=0;
|
594 |
|
|
case(qpmod6)
|
595 |
|
|
0: levelScaleValue = 10;
|
596 |
|
|
1: levelScaleValue = 11;
|
597 |
|
|
2: levelScaleValue = 13;
|
598 |
|
|
3: levelScaleValue = 14;
|
599 |
|
|
4: levelScaleValue = 16;
|
600 |
|
|
5: levelScaleValue = 18;
|
601 |
|
|
default: $display( "ERROR InverseTrans: scalingDC levelScaleGen case default" );
|
602 |
|
|
endcase
|
603 |
|
|
storeValueTemp = zeroExtend(levelScaleValue)*signExtend(workValue);
|
604 |
|
|
if(state==ChromaDC)
|
605 |
|
|
storeValue = truncate( (storeValueTemp << zeroExtend(qpdiv6)) >> 1 );
|
606 |
|
|
else
|
607 |
|
|
begin
|
608 |
|
|
if(qp >= 36)
|
609 |
|
|
storeValue = truncate( storeValueTemp << zeroExtend(qpdiv6 - 2) );
|
610 |
|
|
else
|
611 |
|
|
storeValue = truncate( ((storeValueTemp << 4) + zeroExtend(workOne << zeroExtend(5-qpdiv6))) >> zeroExtend(6 - qpdiv6) );
|
612 |
|
|
end
|
613 |
|
|
storeVector <= update(storeVectorTemp, pixelNum, storeValue);
|
614 |
|
|
if((state==ChromaDC && pixelNum==7) || pixelNum==15)
|
615 |
|
|
begin
|
616 |
|
|
blockNum <= 0;
|
617 |
|
|
pixelNum <= 0;
|
618 |
|
|
workVector <= replicate(0);
|
619 |
|
|
if(state==ChromaDC)
|
620 |
|
|
state <= Chroma;
|
621 |
|
|
else
|
622 |
|
|
state <= Intra16x16;
|
623 |
|
|
process <= Scaling;
|
624 |
|
|
end
|
625 |
|
|
else if((state==ChromaDC && pixelNum>7) || pixelNum>15)
|
626 |
|
|
$display( "ERROR InverseTrans: scalingDC index overflow" );
|
627 |
|
|
else
|
628 |
|
|
pixelNum <= pixelNum+1;
|
629 |
|
|
endrule
|
630 |
|
|
|
631 |
|
|
|
632 |
|
|
rule outputing (process matches Outputing);
|
633 |
|
|
Vector#(4,Bit#(10)) outputVector = replicate(0);
|
634 |
|
|
Vector#(16,Bit#(16)) workVectorTemp = workVector;
|
635 |
|
|
|
636 |
|
|
for(Integer ii=0; ii<4; ii=ii+1)
|
637 |
|
|
outputVector[ii] = truncate((workVectorTemp[pixelNum+fromInteger(ii)]+32) >> 6);
|
638 |
|
|
outfifo.enq(ITBresidual outputVector);
|
639 |
|
|
Int#(10) tempint = unpack(outputVector[0]);
|
640 |
|
|
$display("ccl3IBTresidual %0d", tempint);
|
641 |
|
|
tempint = unpack(outputVector[1]);
|
642 |
|
|
$display("ccl3IBTresidual %0d", tempint);
|
643 |
|
|
tempint = unpack(outputVector[2]);
|
644 |
|
|
$display("ccl3IBTresidual %0d", tempint);
|
645 |
|
|
tempint = unpack(outputVector[3]);
|
646 |
|
|
$display("ccl3IBTresidual %0d", tempint);
|
647 |
|
|
pixelNum <= pixelNum+4;
|
648 |
|
|
if(pixelNum==12)
|
649 |
|
|
begin
|
650 |
|
|
workVector <= replicate(0);
|
651 |
|
|
if(state==Chroma)
|
652 |
|
|
begin
|
653 |
|
|
if(blockNum<7)
|
654 |
|
|
begin
|
655 |
|
|
blockNum <= blockNum+1;
|
656 |
|
|
process <= Scaling;
|
657 |
|
|
end
|
658 |
|
|
else if (blockNum==7)
|
659 |
|
|
begin
|
660 |
|
|
blockNum <= 0;
|
661 |
|
|
process <= Passing;
|
662 |
|
|
end
|
663 |
|
|
else
|
664 |
|
|
$display( "ERROR InverseTrans: outputing chroma unexpected blockNum" );
|
665 |
|
|
end
|
666 |
|
|
else
|
667 |
|
|
begin
|
668 |
|
|
blockNum <= blockNum+1;
|
669 |
|
|
if(blockNum==15)
|
670 |
|
|
begin
|
671 |
|
|
state <= ChromaDC;
|
672 |
|
|
process <= LoadingDC;
|
673 |
|
|
end
|
674 |
|
|
else
|
675 |
|
|
process <= Scaling;
|
676 |
|
|
end
|
677 |
|
|
end
|
678 |
|
|
endrule
|
679 |
|
|
|
680 |
|
|
|
681 |
|
|
|
682 |
|
|
interface Put ioin = fifoToPut(infifo);
|
683 |
|
|
interface Get ioout = fifoToGet(outfifo);
|
684 |
|
|
|
685 |
|
|
|
686 |
|
|
endmodule
|
687 |
|
|
|
688 |
|
|
endpackage
|