OpenCores
URL https://opencores.org/ocsvn/bluespec-h264/bluespec-h264/trunk

Subversion Repositories bluespec-h264

[/] [bluespec-h264/] [trunk/] [release/] [mkInverseTrans.bsv] - Blame information for rev 84

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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