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

Subversion Repositories bluespec-h264

[/] [bluespec-h264/] [trunk/] [src/] [mkDeblockFilter.bsv] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 jamey.hick
//**********************************************************************
2
// Deblocking Filter
3
//----------------------------------------------------------------------
4
//
5
//
6
 
7
package mkDeblockFilter;
8
 
9
import H264Types::*;
10
 
11
import IDeblockFilter::*;
12
import FIFO::*;
13
import Vector::*;
14
 
15
import Connectable::*;
16
import GetPut::*;
17
import ClientServer::*;
18
 
19
 
20
 
21
 
22
//-----------------------------------------------------------
23
// Local Datatypes
24
//-----------------------------------------------------------
25
 
26
 
27
typedef union tagged
28
{
29
 void     Passing;          //not working on anything in particular
30
 void     Initialize;
31
 void     Horizontal;
32
 void     Vertical;
33
 void     Cleanup;
34
}
35
Process deriving(Eq,Bits);
36
 
37
 
38
 
39
//-----------------------------------------------------------
40
// Helper functions
41
 
42
 
43
function Bit#(8) absdiff8(Bit#(8) in0, Bit#(8) in1);
44
   return (in1>=in0 ? in1-in0 : in0-in1);
45
endfunction
46
 
47
 
48
function Bool filter_test(Bit#(32) in_pixels, Bit#(8) alpha, Bit#(5) beta);
49
   Bit#(8) p1 = in_pixels[7:0];
50
   Bit#(8) p0 = in_pixels[15:8];
51
   Bit#(8) q0 = in_pixels[23:16];
52
   Bit#(8) q1 = in_pixels[31:24];
53
   return((absdiff8(p0,q0) < alpha) &&
54
          (absdiff8(p0,p1) < zeroExtend(beta))  &&
55
          (absdiff8(q0,q1) < zeroExtend(beta)));
56
endfunction
57
 
58
 
59
function Bit#(6) clip3symmetric9to6(Bit#(9) val, Bit#(5) bound);
60
   Int#(9) intval = unpack(val);
61
   Int#(6) intbound = unpack({1'b0,bound});
62
   Int#(6) intout = (intvalsignExtend(intbound) ? intbound : truncate(intval)));
63
   return pack(intout);
64
endfunction
65
 
66
 
67
function Bit#(64) filter_input(Bit#(64) in_pixels, Bool chroma_flag, Bit#(3) bs, Bit#(8) alpha, Bit#(5) beta, Vector#(3,Bit#(5)) tc0_vector);
68
   Bit#(8) p[4];
69
   Bit#(8) q[4];
70
   p[3] = in_pixels[7:0];
71
   p[2] = in_pixels[15:8];
72
   p[1] = in_pixels[23:16];
73
   p[0] = in_pixels[31:24];
74
   q[0] = in_pixels[39:32];
75
   q[1] = in_pixels[47:40];
76
   q[2] = in_pixels[55:48];
77
   q[3] = in_pixels[63:56];
78
   Bit#(8) p_out[4];
79
   Bit#(8) q_out[4];
80
   Bool a_p_test = absdiff8(p[2],p[0]) < zeroExtend(beta);
81
   Bool a_q_test = absdiff8(q[2],q[0]) < zeroExtend(beta);
82
   Bit#(9) p0q0 = zeroExtend(p[0])+zeroExtend(q[0]);
83
   if (bs == 4)
84
      begin
85
         Bool small_gap_test = absdiff8(p[0],q[0]) < (alpha >> 2)+2;
86
         Bit#(11) p_outtemp[3];
87
         Bit#(11) q_outtemp[3];
88
         if (!chroma_flag && a_p_test && small_gap_test)
89
            begin
90
               Bit#(11) sum = zeroExtend(p[1])+zeroExtend(p0q0);
91
               p_outtemp[0] = (zeroExtend(p[2]) + (sum<<1) + zeroExtend(q[1]) + 4) >> 3;
92
               p_outtemp[1] = (zeroExtend(p[2]) + sum + 2) >> 2;
93
               p_outtemp[2] = (((zeroExtend(p[3])+zeroExtend(p[2]))<<1) + zeroExtend(p[2]) + sum + 4) >> 3;
94
            end
95
         else
96
            begin
97
               p_outtemp[0] = ((zeroExtend(p[1])<<1) + zeroExtend(p[0]) + zeroExtend(q[1]) + 2) >> 2;
98
               p_outtemp[1] = zeroExtend(p[1]);
99
               p_outtemp[2] = zeroExtend(p[2]);
100
            end
101
         if (!chroma_flag && a_q_test && small_gap_test)
102
            begin
103
               Bit#(11) sum = zeroExtend(q[1])+zeroExtend(p0q0);
104
               q_outtemp[0] = (zeroExtend(p[1]) + (sum<<1) + zeroExtend(q[2]) + 4) >> 3;
105
               q_outtemp[1] = (zeroExtend(q[2]) + sum + 2) >> 2;
106
               q_outtemp[2] = (((zeroExtend(q[3])+zeroExtend(q[2]))<<1) + zeroExtend(q[2]) + sum + 4) >> 3;
107
            end
108
         else
109
            begin
110
               q_outtemp[0] = ((zeroExtend(q[1])<<1) + zeroExtend(q[0]) + zeroExtend(p[1]) + 2) >> 2;
111
               q_outtemp[1] = zeroExtend(q[1]);
112
               q_outtemp[2] = zeroExtend(q[2]);
113
            end
114
         p_out[0] = truncate(p_outtemp[0]);
115
         p_out[1] = truncate(p_outtemp[1]);
116
         p_out[2] = truncate(p_outtemp[2]);
117
         q_out[0] = truncate(q_outtemp[0]);
118
         q_out[1] = truncate(q_outtemp[1]);
119
         q_out[2] = truncate(q_outtemp[2]);
120
      end
121
   else if(bs > 0)
122
      begin
123
         Bit#(5) t_c0 = tc0_vector[bs-1];
124
         Bit#(5) t_c = chroma_flag ? t_c0+1 : t_c0 + (a_p_test ? 1:0) + (a_q_test ? 1:0);
125
         Bit#(12) deltatemp = (((zeroExtend(q[0])-zeroExtend(p[0]))<<2)+zeroExtend(p[1])-zeroExtend(q[1])+4);
126
         Bit#(6) delta = clip3symmetric9to6(deltatemp[11:3],t_c);
127
 
128
         Bit#(10) p_out0temp = zeroExtend(p[0]) + signExtend(delta);
129
         p_out[0] = (p_out0temp[9]==1 ? 0 : (p_out0temp[8]==1 ? 255 : p_out0temp[7:0]));
130
         Bit#(10) q_out0temp = zeroExtend(q[0]) - signExtend(delta);
131
         q_out[0] = (q_out0temp[9]==1 ? 0 : (q_out0temp[8]==1 ? 255 : q_out0temp[7:0]));
132
 
133
         Bit#(9) p0q0PLUS1 = p0q0+1;
134
         Bit#(8) p0q0_av = p0q0PLUS1[8:1];
135
         if (!chroma_flag && a_p_test)
136
            begin
137
               Bit#(10) p_out1temp = zeroExtend(p[2]) + zeroExtend(p0q0_av) - (zeroExtend(p[1])<<1);
138
               p_out[1] = p[1]+signExtend(clip3symmetric9to6(p_out1temp[9:1],t_c0));
139
            end
140
         else
141
            p_out[1] = p[1];
142
 
143
         if (!chroma_flag && a_q_test)
144
            begin
145
               Bit#(10) q_out1temp = zeroExtend(q[2]) + zeroExtend(p0q0_av) - (zeroExtend(q[1])<<1);
146
               q_out[1] = q[1]+signExtend(clip3symmetric9to6(q_out1temp[9:1],t_c0));
147
            end
148
         else
149
            q_out[1] = q[1];
150
 
151
         p_out[2] = p[2];
152
         q_out[2] = q[2];
153
      end
154
   else
155
      begin
156
         p_out[0] = p[0];
157
         q_out[0] = q[0];
158
         p_out[1] = p[1];
159
         q_out[1] = q[1];
160
         p_out[2] = p[2];
161
         q_out[2] = q[2];
162
      end
163
   p_out[3] = p[3];
164
   q_out[3] = q[3];
165
   return({q_out[3], q_out[2], q_out[1], q_out[0], p_out[0], p_out[1], p_out[2], p_out[3]});
166
endfunction
167
 
168
 
169
 
170
//-----------------------------------------------------------
171
// Deblocking Filter Module
172
//-----------------------------------------------------------
173
 
174
 
175
(* synthesize *)
176
module mkDeblockFilter( IDeblockFilter );
177
 
178
   FIFO#(EntropyDecOT) infifo     <- mkSizedFIFO(deblockFilter_infifo_size);
179
   FIFO#(DeblockFilterOT) outfifo <- mkFIFO();
180
 
181
   FIFO#(MemReq#(TAdd#(PicWidthSz,5),32)) dataMemReqQ       <- mkFIFO;
182
   FIFO#(MemReq#(PicWidthSz,13))          parameterMemReqQ  <- mkFIFO;
183
   FIFO#(MemResp#(32))                    dataMemRespQ      <- mkFIFO;
184
   FIFO#(MemResp#(13))                    parameterMemRespQ <- mkFIFO;
185
 
186
   Reg#(Process) process       <- mkReg(Passing);
187
   Reg#(Bit#(1)) chromaFlag    <- mkReg(0);
188
   Reg#(Bit#(5)) dataReqCount  <- mkReg(0);
189
   Reg#(Bit#(5)) dataRespCount <- mkReg(0);
190
   Reg#(Bit#(4)) blockNum      <- mkReg(0);
191
   Reg#(Bit#(4)) pixelNum      <- mkReg(0);
192
 
193
   Reg#(Bool) filterTopMbEdgeFlag     <- mkReg(False);
194
   Reg#(Bool) filterLeftMbEdgeFlag    <- mkReg(False);
195
   Reg#(Bool) filterInternalEdgesFlag <- mkReg(False);
196
 
197
   Reg#(Bit#(PicWidthSz))  picWidth  <- mkReg(maxPicWidthInMB);
198
   Reg#(Bit#(PicHeightSz)) picHeight <- mkReg(0);
199
   Reg#(Bit#(PicAreaSz))   firstMb   <- mkReg(0);
200
   Reg#(Bit#(PicAreaSz))   currMb    <- mkReg(0);
201
   Reg#(Bit#(PicAreaSz))   currMbHor <- mkReg(0);//horizontal position of currMb
202
   Reg#(Bit#(PicHeightSz)) currMbVer <- mkReg(0);//vertical position of currMb
203
 
204
   Reg#(Bit#(2)) disable_deblocking_filter_idc <- mkReg(0);
205
   Reg#(Bit#(5)) slice_alpha_c0_offset <- mkReg(0);
206
   Reg#(Bit#(5)) slice_beta_offset <- mkReg(0);
207
 
208
   Reg#(Bit#(6)) curr_qpy   <- mkReg(0);
209
   Reg#(Bit#(6)) left_qpy   <- mkReg(0);
210
   Reg#(Bit#(6)) top_qpy    <- mkReg(0);
211
   Reg#(Bit#(6)) curr_qpc   <- mkReg(0);
212
   Reg#(Bit#(6)) left_qpc   <- mkReg(0);
213
   Reg#(Bit#(6)) top_qpc    <- mkReg(0);
214
   Reg#(Bit#(1)) curr_intra <- mkReg(0);
215
   Reg#(Bit#(1)) left_intra <- mkReg(0);
216
   Reg#(Bit#(1)) top_intra  <- mkReg(0);
217
 
218
   Reg#(Bit#(8)) alphaMbEdge    <- mkReg(0);
219
   Reg#(Bit#(8)) alphaInternal  <- mkReg(0);
220
   Reg#(Bit#(5)) betaMbEdge     <- mkReg(0);
221
   Reg#(Bit#(5)) betaInternal   <- mkReg(0);
222
   Reg#(Vector#(3,Bit#(5))) tc0MbEdge   <- mkRegU();
223
   Reg#(Vector#(3,Bit#(5))) tc0Internal <- mkRegU();
224
 
225
   Bit#(8) alpha_table[52] = {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
226
                              0,  0,  0,  0,  0,  0,  4,  4,  5,  6,
227
                              7,  8,  9, 10, 12, 13, 15, 17, 20, 22,
228
                             25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
229
                             80, 90,101,113,127,144,162,182,203,226,
230
                            255,255};
231
   Bit#(5) beta_table[52] = {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
232
                             0,  0,  0,  0,  0,  0,  2,  2,  2,  3,
233
                             3,  3,  3,  4,  4,  4,  6,  6,  7,  7,
234
                             8,  8,  9,  9, 10, 10, 11, 11, 12, 12,
235
                            13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
236
                            18, 18};
237
   Bit#(5) tc0_table[52][3] = {{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
238
                               { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
239
                               { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 1 },
240
                               { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 0, 1, 1 }, { 1, 1, 1 },
241
                               { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 2 }, { 1, 1, 2 },
242
                               { 1, 1, 2 }, { 1, 2, 3 }, { 1, 2, 3 }, { 2, 2, 3 }, { 2, 2, 4 }, { 2, 3, 4 },
243
                               { 2, 3, 4 }, { 3, 3, 5 }, { 3, 4, 6 }, { 3, 4, 6 }, { 4, 5, 7 }, { 4, 5, 8 },
244
                               { 4, 6, 9 }, { 5, 7,10 }, { 6, 8,11 }, { 6, 8,13 }, { 7,10,14 }, { 8,11,16 },
245
                               { 9,12,18 }, {10,13,20 }, {11,15,23 }, {13,17,25 }};
246
 
247
   Reg#(Vector#(64,Bit#(32))) workVector <- mkRegU();
248
   Reg#(Vector#(96,Bit#(32))) leftVector <- mkRegU();
249
   Reg#(Vector#(16,Bit#(32))) topVector  <- mkRegU();
250
 
251
   Reg#(Bool) startLastOutput <- mkReg(False);
252
   Reg#(Bool) outputingFinished <- mkReg(False);
253
   Reg#(Bit#(2)) colNum <- mkReg(0);
254
   Reg#(Bit#(2)) rowNum <- mkReg(0);
255
 
256
   RFile1#(Bit#(4),Tuple2#(Bit#(3),Bit#(3))) bSfile <- mkRFile1Full();
257
 
258
 
259
   //-----------------------------------------------------------
260
   // Rules
261
 
262
 
263
   rule checkFIFO ( True );
264
      $display( "Trace DeblockFilter: checkFIFO %h", infifo.first() );
265
   endrule
266
 
267
 
268
   rule passing ( process matches Passing );
269
      case (infifo.first()) matches
270
         tagged NewUnit . xdata :
271
            begin
272
               infifo.deq();
273
               outfifo.enq(EDOT infifo.first());
274
               $display("ccl5newunit");
275
               $display("ccl5rbspbyte %h", xdata);
276
            end
277
         tagged SPSpic_width_in_mbs .xdata :
278
            begin
279
               infifo.deq();
280
               outfifo.enq(EDOT infifo.first());
281
               picWidth <= xdata;
282
            end
283
         tagged SPSpic_height_in_map_units .xdata :
284
            begin
285
               infifo.deq();
286
               outfifo.enq(EDOT infifo.first());
287
               picHeight <= xdata;
288
            end
289
         tagged PPSdeblocking_filter_control_present_flag .xdata :
290
            begin
291
               infifo.deq();
292
               if (xdata == 0)
293
                  begin
294
                     disable_deblocking_filter_idc <= 0;
295
                     slice_alpha_c0_offset <= 0;
296
                     slice_beta_offset <= 0;
297
                  end
298
            end
299
         tagged SHfirst_mb_in_slice .xdata :
300
            begin
301
               infifo.deq();
302
               outfifo.enq(EDOT infifo.first());
303
               firstMb   <= xdata;
304
               currMb    <= xdata;
305
               currMbHor <= xdata;
306
               currMbVer <= 0;
307
            end
308
         tagged SHdisable_deblocking_filter_idc .xdata :
309
            begin
310
               infifo.deq();
311
               disable_deblocking_filter_idc <= xdata;
312
            end
313
         tagged SHslice_alpha_c0_offset .xdata :
314
            begin
315
               infifo.deq();
316
               slice_alpha_c0_offset <= xdata;
317
            end
318
         tagged SHslice_beta_offset .xdata :
319
            begin
320
               infifo.deq();
321
               slice_beta_offset <= xdata;
322
            end
323
         tagged IBTmb_qp .xdata :
324
            begin
325
               infifo.deq();
326
               curr_qpy <= xdata.qpy;
327
               curr_qpc <= xdata.qpc;
328
            end
329
         tagged PBbS .xdata :
330
            begin
331
               process <= Initialize;
332
            end
333
         tagged PBoutput .xdata :
334
            begin
335
               $display( "ERROR Deblocking Filter: passing PBoutput");
336
            end
337
         tagged EndOfFile :
338
            begin
339
               infifo.deq();
340
               outfifo.enq(EDOT infifo.first());
341
               $display( "ccl5: EndOfFile reached");
342
               //$finish(0);
343
            end
344
         default:
345
            begin
346
               infifo.deq();
347
               outfifo.enq(EDOT infifo.first());
348
            end
349
      endcase
350
   endrule
351
 
352
 
353
   rule currMbHorUpdate( !(currMbHor
354
      Bit#(PicAreaSz) temp = zeroExtend(picWidth);
355
      if((currMbHor >> 3) >= temp)
356
         begin
357
            currMbHor <= currMbHor - (temp << 3);
358
            currMbVer <= currMbVer + 8;
359
         end
360
      else
361
         begin
362
            currMbHor <= currMbHor - temp;
363
            currMbVer <= currMbVer + 1;
364
         end
365
   endrule
366
 
367
 
368
   rule initialize ( process==Initialize && currMbHor
369
      //$display( "TRACE Deblocking Filter: initialize %0d", currMb);
370
      process <= Horizontal;
371
      dataReqCount <= 1;
372
      dataRespCount <= 1;
373
      filterTopMbEdgeFlag <= !(currMb
374
      filterLeftMbEdgeFlag <= !(currMbHor==0 || disable_deblocking_filter_idc==1 || (disable_deblocking_filter_idc==2 && currMb==firstMb));
375
      filterInternalEdgesFlag <= !(disable_deblocking_filter_idc==1);
376
      blockNum <= 0;
377
      pixelNum <= 0;
378
      Bit#(6) curr_qp = (chromaFlag==0 ? curr_qpy : curr_qpc);
379
      Bit#(6) left_qp = (chromaFlag==0 ? left_qpy : left_qpc);
380
      Bit#(7) qpavtemp = zeroExtend(curr_qp)+zeroExtend(left_qp)+1;
381
      Bit#(6) qpav = qpavtemp[6:1];
382
      Bit#(8) indexAtemp = zeroExtend(qpav)+signExtend(slice_alpha_c0_offset);
383
      Bit#(8) indexBtemp = zeroExtend(qpav)+signExtend(slice_beta_offset);
384
      Bit#(6) indexA = (indexAtemp[7]==1 ? 0 : (indexAtemp[6:0]>51 ? 51 : indexAtemp[5:0]));
385
      Bit#(6) indexB = (indexBtemp[7]==1 ? 0 : (indexBtemp[6:0]>51 ? 51 : indexBtemp[5:0]));
386
      alphaMbEdge <= alpha_table[indexA];
387
      betaMbEdge <= beta_table[indexB];
388
      Vector#(3,Bit#(5)) tc0temp = arrayToVector(tc0_table[indexA]);
389
      tc0MbEdge <= tc0temp;
390
   endrule
391
 
392
 
393
   rule dataSendReq ( dataReqCount>0 && currMbHor
394
      //$display( "TRACE Deblocking Filter: dataSendReq %0d", dataReqCount);
395
      Bit#(PicWidthSz) temp = truncate(currMbHor);
396
      if(currMb
397
         dataReqCount <= 0;
398
      else
399
         begin
400
            if(dataReqCount==1)
401
               parameterMemReqQ.enq(LoadReq temp);
402
            Bit#(4) temp2 = truncate(dataReqCount-1);
403
            let temp3 = {temp,chromaFlag,temp2};
404
            dataMemReqQ.enq(LoadReq temp3);
405
            if(dataReqCount==16)
406
               dataReqCount <= 0;
407
            else
408
               dataReqCount <= dataReqCount+1;
409
         end
410
   endrule
411
 
412
 
413
   rule dataReceiveNoResp ( dataRespCount>0 && currMb
414
      //$display( "TRACE Deblocking Filter: dataReceiveNoResp");
415
      dataRespCount <= 0;
416
   endrule
417
 
418
 
419
   rule dataReceiveResp ( dataRespCount>0 && !(currMb
420
      //$display( "TRACE Deblocking Filter: dataReceiveResp %0d", dataRespCount);
421
      Bit#(4) temp = truncate(dataRespCount-1);
422
      Vector#(16,Bit#(32)) topVectorNext = topVector;
423
      if(dataRespCount==1)
424
         begin
425
            Bit#(13) tempParameters=0;
426
            if(parameterMemRespQ.first() matches tagged LoadResp .xdata)
427
               tempParameters = xdata;
428
            top_qpy <= tempParameters[5:0];
429
            top_qpc <= tempParameters[11:6];
430
            top_intra <= tempParameters[12];
431
            parameterMemRespQ.deq();
432
         end
433
      if(dataRespCount==16)
434
         dataRespCount <= 0;
435
      else
436
         dataRespCount <= dataRespCount+1;
437
      if(dataMemRespQ.first() matches tagged LoadResp .xdata)
438
            topVectorNext[temp] = xdata;
439
      dataMemRespQ.deq();
440
      topVector <= topVectorNext;
441
      //$display( "TRACE Deblocking Filter: dataReceiveResp topVector %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h", topVector[0], topVector[1], topVector[2], topVector[3], topVector[4], topVector[5], topVector[6], topVector[7], topVector[8], topVector[9], topVector[10], topVector[11], topVector[12], topVector[13], topVector[14], topVector[15]);
442
   endrule
443
 
444
 
445
   rule horizontal ( process==Horizontal && currMbHor
446
      //$display( "TRACE Deblocking Filter: horizontal %0d %0d %0d", blockNum, pixelNum, infifo.first());
447
      Bit#(2) blockHor = {blockNum[2],blockNum[0]};
448
      Bit#(2) blockVer = {blockNum[3],blockNum[1]};
449
      Bit#(2) pixelVer = {pixelNum[3],pixelNum[2]};
450
      Vector#(96,Bit#(32)) leftVectorNext = leftVector;
451
      Vector#(64,Bit#(32)) workVectorNext = workVector;
452
      Bool leftEdge = (blockNum[0]==0 && (blockNum[2]==0 || chromaFlag==1));
453
      if(blockNum==0 && pixelNum==0)
454
         begin
455
            Bit#(6) qpav = (chromaFlag==0 ? curr_qpy : curr_qpc);
456
            Bit#(8) indexAtemp = zeroExtend(qpav)+signExtend(slice_alpha_c0_offset);
457
            Bit#(8) indexBtemp = zeroExtend(qpav)+signExtend(slice_beta_offset);
458
            Bit#(6) indexA = (indexAtemp[7]==1 ? 0 : (indexAtemp[6:0]>51 ? 51 : indexAtemp[5:0]));
459
            Bit#(6) indexB = (indexBtemp[7]==1 ? 0 : (indexBtemp[6:0]>51 ? 51 : indexBtemp[5:0]));
460
            alphaInternal <= alpha_table[indexA];
461
            betaInternal <= beta_table[indexB];
462
            Vector#(3,Bit#(5)) tc0temp = arrayToVector(tc0_table[indexA]);
463
            tc0Internal <= tc0temp;
464
         end
465
      case (infifo.first()) matches
466
         tagged PBbS .xdata :
467
            begin
468
               infifo.deq();
469
               bSfile.upd(blockNum,tuple2(xdata.bShor,xdata.bSver));
470
            end
471
         tagged PBoutput .xdata :
472
            begin
473
               infifo.deq();
474
               Bit#(6) addrq = {blockHor,blockVer,pixelVer};
475
               Bit#(7) addrpLeft = (chromaFlag==0 ? {3'b011,blockVer,pixelVer} : {2'b10,blockHor[1],1'b1,blockVer[0],pixelVer});
476
               Bit#(6) addrpCurr = {(blockHor-1),blockVer,pixelVer};
477
               Bit#(32) pixelq = {xdata[3],xdata[2],xdata[1],xdata[0]};
478
               Bit#(32) pixelp;
479
               if(leftEdge)
480
                  pixelp = leftVector[addrpLeft];
481
               else
482
                  pixelp = workVector[addrpCurr];
483
               Bit#(64) result = {pixelq,pixelp};
484
               if(leftEdge && filterLeftMbEdgeFlag)
485
                  begin
486
                     if(filter_test({pixelq[15:0],pixelp[31:16]},alphaMbEdge,betaMbEdge))
487
                        result = filter_input({pixelq,pixelp},chromaFlag==1,tpl_1(bSfile.sub((chromaFlag==0?blockNum:{blockNum[1:0],pixelVer[1],1'b0}))),alphaMbEdge,betaMbEdge,tc0MbEdge);
488
                  end
489
               else if(!leftEdge && filterInternalEdgesFlag)
490
                  begin
491
                     if(filter_test({pixelq[15:0],pixelp[31:16]},alphaInternal,betaInternal))
492
                        result = filter_input({pixelq,pixelp},chromaFlag==1,tpl_1(bSfile.sub((chromaFlag==0?blockNum:{blockNum[1:0],pixelVer[1],1'b0}))),alphaInternal,betaInternal,tc0Internal);
493
                  end
494
               if(leftEdge)
495
                  leftVectorNext[addrpLeft] = result[31:0];
496
               else
497
                  workVectorNext[addrpCurr] = result[31:0];
498
               workVectorNext[addrq] = result[63:32];
499
               leftVector <= leftVectorNext;
500
               workVector <= workVectorNext;
501
               if(pixelNum==12 && (blockNum==15 || (blockNum==7 && chromaFlag==1)))
502
                  begin
503
                     blockNum <= 0;
504
                     process <= Vertical;
505
                     startLastOutput <= False;
506
                     outputingFinished <= False;
507
                     colNum <= 0;
508
                     if(filterTopMbEdgeFlag)
509
                        rowNum <= 0;
510
                     else
511
                        rowNum <= 1;
512
                     Bit#(6) curr_qp = (chromaFlag==0 ? curr_qpy : curr_qpc);
513
                     Bit#(6) top_qp = (chromaFlag==0 ? top_qpy : top_qpc);
514
                     Bit#(7) qpavtemp = zeroExtend(curr_qp)+zeroExtend(top_qp)+1;
515
                     Bit#(6) qpav = qpavtemp[6:1];
516
                     Bit#(8) indexAtemp = zeroExtend(qpav)+signExtend(slice_alpha_c0_offset);
517
                     Bit#(8) indexBtemp = zeroExtend(qpav)+signExtend(slice_beta_offset);
518
                     Bit#(6) indexA = (indexAtemp[7]==1 ? 0 : (indexAtemp[6:0]>51 ? 51 : indexAtemp[5:0]));
519
                     Bit#(6) indexB = (indexBtemp[7]==1 ? 0 : (indexBtemp[6:0]>51 ? 51 : indexBtemp[5:0]));
520
                     alphaMbEdge <= alpha_table[indexA];
521
                     betaMbEdge <= beta_table[indexB];
522
                     Vector#(3,Bit#(5)) tc0temp = arrayToVector(tc0_table[indexA]);
523
                     tc0MbEdge <= tc0temp;
524
                  end
525
               else if(pixelNum==12)
526
                  blockNum <= blockNum+1;
527
               pixelNum <= pixelNum+4;
528
            end
529
         default: $display( "ERROR Deblocking Filter: horizontal non-PBoutput input");
530
      endcase
531
   endrule
532
 
533
 
534
   rule vertical ( process==Vertical && !startLastOutput && dataRespCount==0 && currMbHor
535
      //$display( "TRACE Deblocking Filter: vertical %0d %0d", colNum, rowNum);
536
      //$display( "TRACE Deblocking Filter: vertical topVector %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h", topVector[0], topVector[1], topVector[2], topVector[3], topVector[4], topVector[5], topVector[6], topVector[7], topVector[8], topVector[9], topVector[10], topVector[11], topVector[12], topVector[13], topVector[14], topVector[15]);
537
      Bool topEdge = (rowNum==0);
538
      Vector#(64,Bit#(32)) workVectorNext = workVector;
539
      Vector#(16,Bit#(32)) topVectorNext = topVector;
540
      Vector#(64,Bit#(32)) workV = workVector;
541
      Vector#(4,Bit#(32)) tempV = replicate(0);
542
      Vector#(4,Bit#(64)) resultV = replicate(0);
543
      Bit#(8) alpha;
544
      Bit#(5) beta;
545
      Vector#(3,Bit#(5)) tc0;
546
      Bit#(4) crNum = {colNum,rowNum};
547
      if(topEdge)
548
         begin
549
            tempV[0] = topVector[{colNum,2'b00}];
550
            tempV[1] = topVector[{colNum,2'b01}];
551
            tempV[2] = topVector[{colNum,2'b10}];
552
            tempV[3] = topVector[{colNum,2'b11}];
553
            alpha = alphaMbEdge;
554
            beta = betaMbEdge;
555
            tc0 = tc0MbEdge;
556
         end
557
      else
558
         begin
559
            tempV[0] = workV[{(crNum-1),2'b00}];
560
            tempV[1] = workV[{(crNum-1),2'b01}];
561
            tempV[2] = workV[{(crNum-1),2'b10}];
562
            tempV[3] = workV[{(crNum-1),2'b11}];
563
            alpha = alphaInternal;
564
            beta = betaInternal;
565
            tc0 = tc0Internal;
566
         end
567
      resultV[0] = {workV[{crNum,2'b11}][7:0],workV[{crNum,2'b10}][7:0],workV[{crNum,2'b01}][7:0],workV[{crNum,2'b00}][7:0],tempV[3][7:0],tempV[2][7:0],tempV[1][7:0],tempV[0][7:0]};
568
      resultV[1] = {workV[{crNum,2'b11}][15:8],workV[{crNum,2'b10}][15:8],workV[{crNum,2'b01}][15:8],workV[{crNum,2'b00}][15:8],tempV[3][15:8],tempV[2][15:8],tempV[1][15:8],tempV[0][15:8]};
569
      resultV[2] = {workV[{crNum,2'b11}][23:16],workV[{crNum,2'b10}][23:16],workV[{crNum,2'b01}][23:16],workV[{crNum,2'b00}][23:16],tempV[3][23:16],tempV[2][23:16],tempV[1][23:16],tempV[0][23:16]};
570
      resultV[3] = {workV[{crNum,2'b11}][31:24],workV[{crNum,2'b10}][31:24],workV[{crNum,2'b01}][31:24],workV[{crNum,2'b00}][31:24],tempV[3][31:24],tempV[2][31:24],tempV[1][31:24],tempV[0][31:24]};
571
      if(filter_test({workV[{crNum,2'b01}][7:0],workV[{crNum,2'b00}][7:0],tempV[3][7:0],tempV[2][7:0]},alpha,beta))
572
         resultV[0] = filter_input(resultV[0],chromaFlag==1,tpl_2(bSfile.sub((chromaFlag==0?{rowNum[1],colNum[1],rowNum[0],colNum[0]}:{rowNum[0],colNum[0],2'b00}))),alpha,beta,tc0);
573
      if(filter_test({workV[{crNum,2'b01}][15:8],workV[{crNum,2'b00}][15:8],tempV[3][15:8],tempV[2][15:8]},alpha,beta))
574
         resultV[1] = filter_input(resultV[1],chromaFlag==1,tpl_2(bSfile.sub((chromaFlag==0?{rowNum[1],colNum[1],rowNum[0],colNum[0]}:{rowNum[0],colNum[0],2'b00}))),alpha,beta,tc0);
575
      if(filter_test({workV[{crNum,2'b01}][23:16],workV[{crNum,2'b00}][23:16],tempV[3][23:16],tempV[2][23:16]},alpha,beta))
576
         resultV[2] = filter_input(resultV[2],chromaFlag==1,tpl_2(bSfile.sub((chromaFlag==0?{rowNum[1],colNum[1],rowNum[0],colNum[0]}:{rowNum[0],colNum[0],2'b01}))),alpha,beta,tc0);
577
      if(filter_test({workV[{crNum,2'b01}][31:24],workV[{crNum,2'b00}][31:24],tempV[3][31:24],tempV[2][31:24]},alpha,beta))
578
         resultV[3] = filter_input(resultV[3],chromaFlag==1,tpl_2(bSfile.sub((chromaFlag==0?{rowNum[1],colNum[1],rowNum[0],colNum[0]}:{rowNum[0],colNum[0],2'b01}))),alpha,beta,tc0);
579
      if(topEdge)
580
         begin
581
            topVectorNext[{colNum,2'b00}] = {resultV[3][7:0],resultV[2][7:0],resultV[1][7:0],resultV[0][7:0]};
582
            topVectorNext[{colNum,2'b01}] = {resultV[3][15:8],resultV[2][15:8],resultV[1][15:8],resultV[0][15:8]};
583
            topVectorNext[{colNum,2'b10}] = {resultV[3][23:16],resultV[2][23:16],resultV[1][23:16],resultV[0][23:16]};
584
            topVectorNext[{colNum,2'b11}] = {resultV[3][31:24],resultV[2][31:24],resultV[1][31:24],resultV[0][31:24]};
585
         end
586
      else
587
         begin
588
            workVectorNext[{(crNum-1),2'b00}] = {resultV[3][7:0],resultV[2][7:0],resultV[1][7:0],resultV[0][7:0]};
589
            workVectorNext[{(crNum-1),2'b01}] = {resultV[3][15:8],resultV[2][15:8],resultV[1][15:8],resultV[0][15:8]};
590
            workVectorNext[{(crNum-1),2'b10}] = {resultV[3][23:16],resultV[2][23:16],resultV[1][23:16],resultV[0][23:16]};
591
            workVectorNext[{(crNum-1),2'b11}] = {resultV[3][31:24],resultV[2][31:24],resultV[1][31:24],resultV[0][31:24]};
592
         end
593
      workVectorNext[{crNum,2'b00}] =  {resultV[3][39:32],resultV[2][39:32],resultV[1][39:32],resultV[0][39:32]};
594
      workVectorNext[{crNum,2'b01}] =  {resultV[3][47:40],resultV[2][47:40],resultV[1][47:40],resultV[0][47:40]};
595
      workVectorNext[{crNum,2'b10}] =  {resultV[3][55:48],resultV[2][55:48],resultV[1][55:48],resultV[0][55:48]};
596
      workVectorNext[{crNum,2'b11}] =  {resultV[3][63:56],resultV[2][63:56],resultV[1][63:56],resultV[0][63:56]};
597
      if(topEdge)
598
         topVector <= topVectorNext;
599
      workVector <= workVectorNext;
600
      if(rowNum==3 || (chromaFlag==1 && rowNum==1))
601
         begin
602
            if(colNum==3)
603
               startLastOutput <= True;
604
            else
605
               begin
606
                  if(filterTopMbEdgeFlag)
607
                     rowNum <= 0;
608
                  else
609
                     rowNum <= 1;
610
               end
611
            colNum <= colNum+1;
612
         end
613
      else
614
        rowNum <= rowNum+1;
615
   endrule
616
 
617
 
618
   rule outputing ( process==Vertical && !outputingFinished && currMbHor
619
      //$display( "TRACE Deblocking Filter: outputting %0d %0d", blockNum, pixelNum);
620
      Bit#(2) blockHor = pixelNum[1:0];
621
      Bit#(2) blockVer = blockNum[1:0];
622
      Bit#(2) pixelVer = pixelNum[3:2];
623
      Bit#(PicWidthSz) currMbHorT = truncate(currMbHor);
624
      Bool stalling = False;
625
      if(currMb==0)
626
         begin
627
            if(startLastOutput)
628
               outputingFinished <= True;
629
         end
630
      else
631
         begin
632
            Bit#(7) leftAddr;
633
            if(chromaFlag==0)
634
               leftAddr = {1'b0,blockHor,blockVer,pixelVer};
635
            else
636
               leftAddr = {2'b10,blockHor,blockVer[0],pixelVer};
637
            Bit#(32) leftData = leftVector[leftAddr];
638
            if(!(blockNum==3 || (blockNum==1 && chromaFlag==1)))
639
               begin
640
                  if(chromaFlag==0)
641
                     outfifo.enq(DFBLuma {ver:{(currMbHorT==0 ? currMbVer-1 : currMbVer),blockVer,pixelVer},hor:{(currMbHorT==0 ? picWidth-1 : currMbHorT-1),blockHor},data:leftData});
642
                  else
643
                     outfifo.enq(DFBChroma {uv:blockHor[1],ver:{(currMbHorT==0 ? currMbVer-1 : currMbVer),blockVer[0],pixelVer},hor:{(currMbHorT==0 ? picWidth-1 : currMbHorT-1),blockHor[0]},data:leftData});
644
               end
645
            else if(startLastOutput)
646
               begin
647
                  Bit#(PicWidthSz) temp = ((currMbHor==0) ? (picWidth-1) : truncate(currMbHor-1));
648
                  dataMemReqQ.enq(StoreReq {addr:{temp,chromaFlag,blockHor,pixelVer},data:leftData});
649
                  if(currMbVer > 0)
650
                     begin
651
                        //$display( "TRACE Deblocking Filter: outputting last output %0d %0d %h", blockHor, pixelVer, topVector[{blockHor,pixelVer}]);
652
                        Bit#(32) topData = topVector[{blockHor,pixelVer}];
653
                        if(chromaFlag==0)
654
                           outfifo.enq(DFBLuma {ver:{currMbVer-1,2'b11,pixelVer},hor:{currMbHorT,blockHor},data:topData});
655
                        else
656
                           outfifo.enq(DFBChroma {uv:blockHor[1],ver:{currMbVer-1,1'b1,pixelVer},hor:{currMbHorT,blockHor[0]},data:topData});
657
                     end
658
               end
659
            else
660
               stalling = True;
661
            if(!stalling)
662
               begin
663
                  if(pixelNum==15)
664
                     begin
665
                        if(blockNum==3 || (chromaFlag==1 && blockNum==1))
666
                           begin
667
                              if(currMbVer==picHeight-1)
668
                                 blockNum <= (chromaFlag==0 ? 3 : 1);
669
                              else
670
                                 blockNum <= 0;
671
                              outputingFinished <= True;
672
                           end
673
                        else
674
                           blockNum <= blockNum+1;
675
                     end
676
                  pixelNum <= pixelNum+1;
677
               end
678
         end
679
   endrule
680
 
681
 
682
   rule verticaltocleanup  ( process==Vertical && startLastOutput && outputingFinished);
683
      process <= Cleanup;
684
      startLastOutput <= False;
685
      outputingFinished <= False;
686
   endrule
687
 
688
 
689
   rule cleanup ( process==Cleanup && currMbHor
690
      //$display( "TRACE Deblocking Filter: cleanup %0d %0d", blockNum, pixelNum);
691
      Bit#(2) blockHor = pixelNum[1:0];
692
      Bit#(2) blockVer = blockNum[1:0];
693
      Bit#(2) pixelVer = pixelNum[3:2];
694
      Bit#(PicWidthSz) currMbHorT = truncate(currMbHor);
695
      Vector#(96,Bit#(32)) leftVectorNext = leftVector;
696
      if(blockNum==0)
697
         begin
698
            if(chromaFlag==0)
699
               begin
700
                  for(Integer ii=0; ii<64; ii=ii+1)
701
                     leftVectorNext[fromInteger(ii)] = workVector[fromInteger(ii)];
702
                  chromaFlag <= 1;
703
                  process <= Initialize;
704
               end
705
            else
706
               begin
707
                  for(Integer ii=0; ii<32; ii=ii+1)
708
                     begin
709
                        Bit#(5) tempAddr = fromInteger(ii);
710
                        leftVectorNext[{2'b10,tempAddr}] = workVector[{tempAddr[4:3],1'b0,tempAddr[2:0]}];
711
                     end
712
                  chromaFlag <= 0;
713
                  process <= Passing;
714
                  Bit#(PicWidthSz) temp = truncate(currMbHor);
715
                  parameterMemReqQ.enq(StoreReq {addr:temp,data:{curr_intra,curr_qpc,curr_qpy}});
716
                  left_intra <= curr_intra;
717
                  left_qpc <= curr_qpc;
718
                  left_qpy <= curr_qpy;
719
                  currMb <= currMb+1;
720
                  currMbHor <= currMbHor+1;
721
                  if(currMbVer==picHeight-1 && currMbHor==zeroExtend(picWidth-1))
722
                     outfifo.enq(EndOfFrame);
723
               end
724
            leftVector <= leftVectorNext;
725
         end
726
      else if(blockNum < 8)
727
         begin
728
            Bit#(7) leftAddr;
729
            if(chromaFlag==0)
730
               leftAddr = {1'b0,blockHor,blockVer,pixelVer};
731
            else
732
               leftAddr = {2'b10,blockHor,blockVer[0],pixelVer};
733
            Bit#(32) leftData = leftVector[leftAddr];
734
            if(chromaFlag==0)
735
               outfifo.enq(DFBLuma {ver:{(currMbHorT==0 ? currMbVer-1 : currMbVer),blockVer,pixelVer},hor:{(currMbHorT==0 ? picWidth-1 : currMbHorT-1),blockHor},data:leftData});
736
            else
737
               outfifo.enq(DFBChroma {uv:blockHor[1],ver:{(currMbHorT==0 ? currMbVer-1 : currMbVer),blockVer[0],pixelVer},hor:{(currMbHorT==0 ? picWidth-1 : currMbHorT-1),blockHor[0]},data:leftData});
738
            if(pixelNum==15)
739
               begin
740
                  if(currMbHor==zeroExtend(picWidth-1))
741
                     blockNum <= 8;
742
                  else
743
                     blockNum <= 0;
744
               end
745
            pixelNum <= pixelNum+1;
746
         end
747
      else
748
         begin
749
            Bit#(6) currAddr = {blockHor,blockVer,pixelVer};
750
            Bit#(32) currData = workVector[currAddr];
751
            if(chromaFlag==0)
752
               outfifo.enq(DFBLuma {ver:{currMbVer,blockVer,pixelVer},hor:{currMbHorT,blockHor},data:currData});
753
            else
754
               outfifo.enq(DFBChroma {uv:blockHor[1],ver:{currMbVer,blockVer[0],pixelVer},hor:{currMbHorT,blockHor[0]},data:currData});
755
            if(pixelNum==15)
756
               begin
757
                  if(blockNum[1:0]==3 || (blockNum[1:0]==1 && chromaFlag==1))
758
                     blockNum <= 0;
759
                  else
760
                     blockNum <= blockNum+1;
761
               end
762
            pixelNum <= pixelNum+1;
763
         end
764
   endrule
765
 
766
 
767
 
768
 
769
 
770
 
771
   interface Client mem_client_data;
772
      interface Get request  = fifoToGet(dataMemReqQ);
773
      interface Put response = fifoToPut(dataMemRespQ);
774
   endinterface
775
 
776
   interface Client mem_client_parameter;
777
      interface Get request  = fifoToGet(parameterMemReqQ);
778
      interface Put response = fifoToPut(parameterMemRespQ);
779
   endinterface
780
 
781
   interface Put ioin  = fifoToPut(infifo);
782
   interface Get ioout = fifoToGet(outfifo);
783
 
784
endmodule
785
 
786
endpackage

powered by: WebSVN 2.1.0

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