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

Subversion Repositories bluespec-h264

[/] [bluespec-h264/] [trunk/] [release/] [mkDeblockFilter.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
// Deblocking Filter
3
//----------------------------------------------------------------------
4
//
5
//
6
 
7
package mkDeblockFilter;
8
 
9
import H264Types::*;
10
 
11
import IDeblockFilter::*;
12
import FIFO::*;
13
import FIFOF::*;
14
import Vector::*;
15
 
16
import Connectable::*;
17
import GetPut::*;
18
import ClientServer::*;
19
import RegFile::*;
20
import RWire::*;
21
 
22
//-----------------------------------------------------------
23
// Local Datatypes
24
//-----------------------------------------------------------
25
 
26
 
27
typedef enum
28
{
29
  Passing,          //not working on anything in particular
30
  Initialize,
31
  Horizontal,
32
  Cleanup,
33
  HorizontalCleanup,
34
  Vertical
35
}
36
Process deriving(Eq,Bits);
37
 
38
typedef enum
39
{
40
  NormalOperation,
41
  VerticalCleanup
42
}
43
VerticalState deriving(Eq,Bits);
44
 
45
//-----------------------------------------------------------
46
// Helper functions
47
 
48
 
49
function Bit#(8) absdiff8(Bit#(8) in0, Bit#(8) in1);
50
   return (in1>=in0 ? in1-in0 : in0-in1);
51
endfunction
52
 
53
 
54
function Bool filter_test(Bit#(32) in_pixels, Bit#(8) alpha, Bit#(5) beta);
55
   Bit#(8) p1 = in_pixels[7:0];
56
   Bit#(8) p0 = in_pixels[15:8];
57
   Bit#(8) q0 = in_pixels[23:16];
58
   Bit#(8) q1 = in_pixels[31:24];
59
   return((absdiff8(p0,q0) < alpha) &&
60
          (absdiff8(p0,p1) < zeroExtend(beta))  &&
61
          (absdiff8(q0,q1) < zeroExtend(beta)));
62
endfunction
63
 
64
 
65
function Bit#(6) clip3symmetric9to6(Bit#(9) val, Bit#(5) bound);
66
   Int#(9) intval = unpack(val);
67
   Int#(6) intbound = unpack({1'b0,bound});
68
   Int#(6) intout = (intvalsignExtend(intbound) ? intbound : truncate(intval)));
69
   return pack(intout);
70
endfunction
71
 
72
 
73
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);
74
   Bit#(8) p[4];
75
   Bit#(8) q[4];
76
   p[3] = in_pixels[7:0];
77
   p[2] = in_pixels[15:8];
78
   p[1] = in_pixels[23:16];
79
   p[0] = in_pixels[31:24];
80
   q[0] = in_pixels[39:32];
81
   q[1] = in_pixels[47:40];
82
   q[2] = in_pixels[55:48];
83
   q[3] = in_pixels[63:56];
84
   Bit#(8) p_out[4];
85
   Bit#(8) q_out[4];
86
   Bool a_p_test = absdiff8(p[2],p[0]) < zeroExtend(beta);
87
   Bool a_q_test = absdiff8(q[2],q[0]) < zeroExtend(beta);
88
   Bit#(9) p0q0 = zeroExtend(p[0])+zeroExtend(q[0]);
89
   if (bs == 4)
90
      begin
91
         Bool small_gap_test = absdiff8(p[0],q[0]) < (alpha >> 2)+2;
92
         Bit#(11) p_outtemp[3];
93
         Bit#(11) q_outtemp[3];
94
         if (!chroma_flag && a_p_test && small_gap_test)
95
            begin
96
               Bit#(11) sum = zeroExtend(p[1])+zeroExtend(p0q0);
97
               p_outtemp[0] = (zeroExtend(p[2]) + (sum<<1) + zeroExtend(q[1]) + 4) >> 3;
98
               p_outtemp[1] = (zeroExtend(p[2]) + sum + 2) >> 2;
99
               p_outtemp[2] = (((zeroExtend(p[3])+zeroExtend(p[2]))<<1) + zeroExtend(p[2]) + sum + 4) >> 3;
100
            end
101
         else
102
            begin
103
               p_outtemp[0] = ((zeroExtend(p[1])<<1) + zeroExtend(p[0]) + zeroExtend(q[1]) + 2) >> 2;
104
               p_outtemp[1] = zeroExtend(p[1]);
105
               p_outtemp[2] = zeroExtend(p[2]);
106
            end
107
         if (!chroma_flag && a_q_test && small_gap_test)
108
            begin
109
               Bit#(11) sum = zeroExtend(q[1])+zeroExtend(p0q0);
110
               q_outtemp[0] = (zeroExtend(p[1]) + (sum<<1) + zeroExtend(q[2]) + 4) >> 3;
111
               q_outtemp[1] = (zeroExtend(q[2]) + sum + 2) >> 2;
112
               q_outtemp[2] = (((zeroExtend(q[3])+zeroExtend(q[2]))<<1) + zeroExtend(q[2]) + sum + 4) >> 3;
113
            end
114
         else
115
            begin
116
               q_outtemp[0] = ((zeroExtend(q[1])<<1) + zeroExtend(q[0]) + zeroExtend(p[1]) + 2) >> 2;
117
               q_outtemp[1] = zeroExtend(q[1]);
118
               q_outtemp[2] = zeroExtend(q[2]);
119
            end
120
         p_out[0] = truncate(p_outtemp[0]);
121
         p_out[1] = truncate(p_outtemp[1]);
122
         p_out[2] = truncate(p_outtemp[2]);
123
         q_out[0] = truncate(q_outtemp[0]);
124
         q_out[1] = truncate(q_outtemp[1]);
125
         q_out[2] = truncate(q_outtemp[2]);
126
      end
127
   else if(bs > 0)
128
      begin
129
         Bit#(5) t_c0 = tc0_vector[bs-1];
130
         Bit#(5) t_c = chroma_flag ? t_c0+1 : t_c0 + (a_p_test ? 1:0) + (a_q_test ? 1:0);
131
         Bit#(12) deltatemp = (((zeroExtend(q[0])-zeroExtend(p[0]))<<2)+zeroExtend(p[1])-zeroExtend(q[1])+4);
132
         Bit#(6) delta = clip3symmetric9to6(deltatemp[11:3],t_c);
133
 
134
         Bit#(10) p_out0temp = zeroExtend(p[0]) + signExtend(delta);
135
         p_out[0] = (p_out0temp[9]==1 ? 0 : (p_out0temp[8]==1 ? 255 : p_out0temp[7:0]));
136
         Bit#(10) q_out0temp = zeroExtend(q[0]) - signExtend(delta);
137
         q_out[0] = (q_out0temp[9]==1 ? 0 : (q_out0temp[8]==1 ? 255 : q_out0temp[7:0]));
138
 
139
         Bit#(9) p0q0PLUS1 = p0q0+1;
140
         Bit#(8) p0q0_av = p0q0PLUS1[8:1];
141
         if (!chroma_flag && a_p_test)
142
            begin
143
               Bit#(10) p_out1temp = zeroExtend(p[2]) + zeroExtend(p0q0_av) - (zeroExtend(p[1])<<1);
144
               p_out[1] = p[1]+signExtend(clip3symmetric9to6(p_out1temp[9:1],t_c0));
145
            end
146
         else
147
            p_out[1] = p[1];
148
 
149
         if (!chroma_flag && a_q_test)
150
            begin
151
               Bit#(10) q_out1temp = zeroExtend(q[2]) + zeroExtend(p0q0_av) - (zeroExtend(q[1])<<1);
152
               q_out[1] = q[1]+signExtend(clip3symmetric9to6(q_out1temp[9:1],t_c0));
153
            end
154
         else
155
            q_out[1] = q[1];
156
 
157
         p_out[2] = p[2];
158
         q_out[2] = q[2];
159
      end
160
   else
161
      begin
162
         p_out[0] = p[0];
163
         q_out[0] = q[0];
164
         p_out[1] = p[1];
165
         q_out[1] = q[1];
166
         p_out[2] = p[2];
167
         q_out[2] = q[2];
168
      end
169
   p_out[3] = p[3];
170
   q_out[3] = q[3];
171
   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]});
172
endfunction
173
 
174
 
175
 
176
 
177
 
178
//-----------------------------------------------------------
179
// Deblocking Filter Module
180
//-----------------------------------------------------------
181
 
182
 
183
//-----------------------------------------------------------
184
// 1 read port register file module
185
 
186
interface RFileSingle#(type idx_t, type d_t);
187
   method Action upd(idx_t x1, d_t x2);
188
   method ActionValue#(d_t) sub(idx_t x1);
189
endinterface
190
 
191
module mkRFileSingle#( idx_t lo, idx_t hi ) ( RFileSingle#(idx_t, d_t) )
192
   provisos (Bits#(idx_t, si),Bits#(d_t, sa));
193
   RegFile#(idx_t,d_t) rf <- mkRegFileWCF(lo,hi);
194
   RWire#(Bit#(0)) sched_hack <- mkRWire();
195
   method Action upd( idx_t index, d_t data );
196
      rf.upd( index, data );
197
   endmethod
198
   method ActionValue#(d_t) sub( idx_t index );
199
      sched_hack.wset(0);
200
      return rf.sub(index);
201
   endmethod
202
endmodule
203
 
204
module mkRFileSingleFull( RFileSingle#(idx_t, d_t) )
205
   provisos (Bits#(idx_t, si),Bits#(d_t, sa),Bounded#(idx_t),Literal#(idx_t) );
206
   RegFile#(idx_t,d_t) rf <- mkRegFileWCF(0,fromInteger(valueof(TSub#(TExp#(si),1))));
207
   RWire#(Bit#(0)) sched_hack <- mkRWire();
208
   method Action upd( idx_t index, d_t data );
209
      rf.upd( index, data );
210
   endmethod
211
   method ActionValue#(d_t) sub( idx_t index );
212
      sched_hack.wset(0);
213
      return rf.sub(index);
214
   endmethod
215
endmodule
216
 
217
 
218
interface ILeftVector;
219
  method ActionValue#(Bit#(32)) sub(Bit#(5) addr);
220
  method Action upd(Bit#(5) addr, Bit#(32) data);
221
endinterface
222
 
223
(*synthesize*)
224
module mkLeftVector(ILeftVector);
225
  RFileSingle#(Bit#(5),Bit#(32)) leftVector <- mkRFileSingleFull;
226
  method sub = leftVector.sub;
227
  method upd = leftVector.upd;
228
endmodule
229
 
230
interface IWorkVectorVer;
231
  method ActionValue#(Bit#(32)) sub(Bit#(4) addr);
232
  method Action upd(Bit#(4) addr, Bit#(32) data);
233
endinterface
234
 
235
(*synthesize*)
236
module mkWorkVectorVer(IWorkVectorVer);
237
  RFileSingle#(Bit#(4),Bit#(32)) workVector <- mkRFileSingleFull();
238
  method sub = workVector.sub;
239
  method upd = workVector.upd;
240
endmodule
241
 
242
interface IWorkVectorHor;
243
  method ActionValue#(Bit#(32)) sub(Bit#(3) addr);
244
  method Action upd(Bit#(3) addr, Bit#(32) data);
245
endinterface
246
 
247
(*synthesize*)
248
module mkWorkVectorHor(IWorkVectorHor);
249
  RFileSingle#(Bit#(3),Bit#(32)) workVector <- mkRFileSingleFull();
250
  method sub = workVector.sub;
251
  method upd = workVector.upd;
252
endmodule
253
 
254
interface ITopVector;
255
  method ActionValue#(Bit#(32)) sub(Bit#(4) addr);
256
  method Action upd(Bit#(4) addr, Bit#(32) data);
257
endinterface
258
 
259
(*synthesize*)
260
module mkTopVector(ITopVector);
261
  RFileSingle#(Bit#(4),Bit#(32)) topVector <- mkRFileSingleFull();
262
  method sub = topVector.sub;
263
  method upd = topVector.upd;
264
endmodule
265
 
266
interface IbSVector;
267
  method ActionValue#(Bit#(3)) sub(Bit#(4) addr);
268
  method Action upd(Bit#(4) addr, Bit#(3) data);
269
endinterface
270
 
271
(*synthesize*)
272
module mkbSVector(IbSVector);
273
  RFileSingle#(Bit#(4),Bit#(3)) bsVector <- mkRFileSingleFull();
274
  method sub = bsVector.sub;
275
  method upd = bsVector.upd;
276
endmodule
277
 
278
 
279
 
280
 
281
 
282
(* synthesize *)
283
module mkDeblockFilter( IDeblockFilter );
284
 
285
   FIFOF#(EntropyDecOT) infifo     <- mkSizedFIFOF(deblockFilter_infifo_size);
286
   FIFO#(DeblockFilterOT) outfifo <- mkFIFO();
287
   FIFO#(DeblockFilterOT) outfifoVertical <- mkSizedFIFO(5);
288
 
289
   FIFO#(MemReq#(TAdd#(PicWidthSz,5),32)) dataMemReqQ       <- mkFIFO;
290
   FIFO#(MemReq#(TAdd#(PicWidthSz,5),32)) memReqRowToColumnConversion <- mkFIFO();
291
   FIFO#(MemReq#(TAdd#(PicWidthSz,5),32)) memReqVertical              <- mkFIFO();
292
   FIFO#(MemReq#(TAdd#(PicWidthSz,5),32)) memReqDataSendReq           <- mkFIFO();
293
 
294
   FIFO#(MemReq#(PicWidthSz,13))          parameterMemReqQ  <- mkFIFO;
295
   FIFO#(MemResp#(32))                    dataMemRespQ      <- mkFIFO;
296
   FIFO#(MemResp#(13))                    parameterMemRespQ <- mkFIFO;
297
 
298
   Reg#(Process) process       <- mkReg(Passing);
299
   Reg#(VerticalState) verticalState <- mkReg(NormalOperation);
300
   Reg#(Bit#(1)) chromaFlag    <- mkReg(0);
301
   Reg#(Bit#(5)) dataReqCount  <- mkReg(0);
302
   Reg#(Bit#(5)) dataRespCount <- mkReg(0);
303
   Reg#(Bit#(4)) blockNum      <- mkReg(0);
304
   Reg#(Bit#(2)) pixelNum      <- mkReg(0);
305
 
306
   Reg#(Bool) filterTopMbEdgeFlag     <- mkReg(False);
307
   Reg#(Bool) filterLeftMbEdgeFlag    <- mkReg(False);
308
   Reg#(Bool) filterInternalEdgesFlag <- mkReg(False);
309
 
310
   Reg#(Bit#(PicWidthSz))  picWidth  <- mkReg(maxPicWidthInMB);
311
   Reg#(Bit#(PicHeightSz)) picHeight <- mkReg(0);
312
   Reg#(Bit#(PicAreaSz))   firstMb   <- mkReg(0);
313
   Reg#(Bit#(PicAreaSz))   currMb    <- mkReg(0);
314
   Reg#(Bit#(PicAreaSz))   currMbHor <- mkReg(0);//horizontal position of currMb
315
   Reg#(Bit#(PicHeightSz)) currMbVer <- mkReg(0);//vertical position of currMb
316
 
317
   Reg#(Bit#(2)) disable_deblocking_filter_idc <- mkReg(0);
318
   Reg#(Bit#(5)) slice_alpha_c0_offset <- mkReg(0);
319
   Reg#(Bit#(5)) slice_beta_offset <- mkReg(0);
320
 
321
   Reg#(Bit#(6)) curr_qpy   <- mkReg(0);
322
   Reg#(Bit#(6)) left_qpy   <- mkReg(0);
323
   Reg#(Bit#(6)) top_qpy    <- mkReg(0);
324
   Reg#(Bit#(6)) curr_qpc   <- mkReg(0);
325
   Reg#(Bit#(6)) left_qpc   <- mkReg(0);
326
   Reg#(Bit#(6)) top_qpc    <- mkReg(0);
327
   Reg#(Bit#(1)) curr_intra <- mkReg(0);
328
   Reg#(Bit#(1)) left_intra <- mkReg(0);
329
   Reg#(Bit#(1)) top_intra  <- mkReg(0);
330
 
331
   Reg#(Bit#(2)) blockHorVerticalCleanup <- mkReg(0);
332
 
333
   Reg#(Bit#(8)) alphaInternal  <- mkReg(0);
334
   Reg#(Bit#(5)) betaInternal   <- mkReg(0);
335
   Reg#(Vector#(3,Bit#(5))) tc0Internal <- mkRegU();
336
 
337
   Bit#(8) alpha_table[52] = {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
338
                              0,  0,  0,  0,  0,  0,  4,  4,  5,  6,
339
                              7,  8,  9, 10, 12, 13, 15, 17, 20, 22,
340
                             25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
341
                             80, 90,101,113,127,144,162,182,203,226,
342
                            255,255};
343
   Bit#(5) beta_table[52] = {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
344
                             0,  0,  0,  0,  0,  0,  2,  2,  2,  3,
345
                             3,  3,  3,  4,  4,  4,  6,  6,  7,  7,
346
                             8,  8,  9,  9, 10, 10, 11, 11, 12, 12,
347
                            13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
348
                            18, 18};
349
   Bit#(5) tc0_table[52][3] = {{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
350
                               { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
351
                               { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 1 },
352
                               { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 0, 1, 1 }, { 1, 1, 1 },
353
                               { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 2 }, { 1, 1, 2 },
354
                               { 1, 1, 2 }, { 1, 2, 3 }, { 1, 2, 3 }, { 2, 2, 3 }, { 2, 2, 4 }, { 2, 3, 4 },
355
                               { 2, 3, 4 }, { 3, 3, 5 }, { 3, 4, 6 }, { 3, 4, 6 }, { 4, 5, 7 }, { 4, 5, 8 },
356
                               { 4, 6, 9 }, { 5, 7,10 }, { 6, 8,11 }, { 6, 8,13 }, { 7,10,14 }, { 8,11,16 },
357
                               { 9,12,18 }, {10,13,20 }, {11,15,23 }, {13,17,25 }};
358
 
359
   IWorkVectorHor workVectorRows <- mkWorkVectorHor();
360
   IWorkVectorVer workVectorCols <- mkWorkVectorVer();
361
   ILeftVector leftVector <- mkLeftVector();
362
   ITopVector  topVector  <- mkTopVector();
363
   Reg#(Bit#(16)) topVectorValidBits <- mkReg(0);
364
 
365
   IbSVector bSfileHor <- mkbSVector();
366
   IbSVector bSfileVer <- mkbSVector();
367
 
368
   Reg#(Bit#(6)) cleanup_state <- mkReg(0);
369
 
370
   Vector#(4, FIFO#(Bit#(32))) rowToColumnStore <- replicateM(mkSizedFIFO(3));
371
   Reg#(Bit#(2)) rowToColumnState <- mkReg(0);
372
   FIFO#(Tuple2#(Bit#(4),Bit#(1))) rowToColumnStoreBlock <- mkFIFO(); // The third bit 1 is to rotate the damned
373
                                                                              // last left vector block
374
   FIFO#(Tuple2#(Bit#(4), Bit#(32))) verticalFilterBlock <- mkFIFO();
375
 
376
   Reg#(Bit#(2)) columnState <- mkReg(0);
377
   Vector#(4, FIFO#(Bit#(32))) columnToRowStore <- replicateM(mkSizedFIFO(3));
378
   Reg#(Bit#(2)) columnToRowState <- mkReg(0);
379
   FIFO#(Tuple2#(Bit#(4), Bit#(1))) columnToRowStoreBlock <- mkFIFO();
380
 
381
   Reg#(Bit#(2)) columnNumber <- mkReg(0);
382
 
383
   // Debugging register
384
   Reg#(Bit#(32)) fifo_full_count <- mkReg(0);
385
   Reg#(Bit#(32)) fifo_empty_count <- mkReg(0);
386
   Reg#(Bit#(32)) total_cycles <- mkReg(0);
387
 
388
 
389
   rule incr;
390
     total_cycles <= total_cycles + 1;
391
   endrule
392
 
393
   rule emptyFIFO;
394
     if(!infifo.notEmpty)
395
       begin
396
          fifo_empty_count <= fifo_empty_count + 1;
397
          $display("DEBLOCK FIFO EMPTY: %d of %d",fifo_empty_count, total_cycles);
398
       end
399
   endrule
400
 
401
   rule checkFIFO ( True );
402
      $display( "Trace DeblockFilter: checkFIFO %h cycle: %d", infifo.first(), total_cycles );
403
      $display( "TRACE DeblockFilter: checkFIFO %h", infifo.first() );
404
      if(!infifo.notFull)
405
        begin
406
          fifo_full_count <= fifo_full_count + 1;
407
          $display("DEBLOCK FIFO(%d) FULL: %d of %d",deblockFilter_infifo_size, fifo_full_count, total_cycles);
408
        end
409
   endrule
410
 
411
   rule memReqMergeRowToColumnConversion;
412
     memReqRowToColumnConversion.deq();
413
     dataMemReqQ.enq(memReqRowToColumnConversion.first());
414
   endrule
415
 
416
   rule memReqMergeVertical;
417
     memReqVertical.deq();
418
     dataMemReqQ.enq(memReqVertical.first());
419
   endrule
420
 
421
   rule memReqMergeDataSendReq;
422
     memReqDataSendReq.deq();
423
     dataMemReqQ.enq(memReqDataSendReq.first());
424
   endrule
425
 
426
   rule outfifoVerticalSplit;
427
     outfifoVertical.deq();
428
     outfifo.enq(outfifoVertical.first());
429
   endrule
430
 
431
   rule passing ( process matches Passing );
432
      case (infifo.first()) matches
433
         tagged NewUnit . xdata :
434
            begin
435
               infifo.deq();
436
               outfifo.enq(EDOT (infifo.first()));
437
               $display("ccl5newunit");
438
               $display("ccl5rbspbyte %h", xdata);
439
            end
440
         tagged SPSpic_width_in_mbs .xdata :
441
            begin
442
               infifo.deq();
443
               outfifo.enq(EDOT (infifo.first()));
444
               picWidth <= xdata;
445
            end
446
         tagged SPSpic_height_in_map_units .xdata :
447
            begin
448
               infifo.deq();
449
               outfifo.enq(EDOT (infifo.first()));
450
               picHeight <= xdata;
451
            end
452
         tagged PPSdeblocking_filter_control_present_flag .xdata :
453
            begin
454
               infifo.deq();
455
               if (xdata == 0)
456
                  begin
457
                     disable_deblocking_filter_idc <= 0;
458
                     slice_alpha_c0_offset <= 0;
459
                     slice_beta_offset <= 0;
460
                  end
461
            end
462
         tagged SHfirst_mb_in_slice .xdata :
463
            begin
464
               infifo.deq();
465
               outfifo.enq(EDOT (infifo.first()));
466
               firstMb   <= xdata;
467
               currMb    <= xdata;
468
               currMbHor <= xdata;
469
               currMbVer <= 0;
470
            end
471
         tagged SHdisable_deblocking_filter_idc .xdata :
472
            begin
473
               infifo.deq();
474
               disable_deblocking_filter_idc <= xdata;
475
            end
476
         tagged SHslice_alpha_c0_offset .xdata :
477
            begin
478
               infifo.deq();
479
               slice_alpha_c0_offset <= xdata;
480
            end
481
         tagged SHslice_beta_offset .xdata :
482
            begin
483
               infifo.deq();
484
               slice_beta_offset <= xdata;
485
            end
486
         tagged IBTmb_qp .xdata :
487
            begin
488
               infifo.deq();
489
               curr_qpy <= xdata.qpy;
490
               curr_qpc <= xdata.qpc;
491
            end
492
         tagged PBbS .xdata :
493
            begin
494
               process <= Initialize;
495
            end
496
         tagged PBoutput .xdata :
497
            begin
498
               $display( "ERROR Deblocking Filter: passing PBoutput");
499
            end
500
         tagged EndOfFile :
501
            begin
502
               infifo.deq();
503
               outfifo.enq(EDOT (infifo.first()));
504
               $display( "ccl5: EndOfFile reached");
505
               //$finish(0);
506
            end
507
         default:
508
            begin
509
               infifo.deq();
510
               outfifo.enq(EDOT (infifo.first()));
511
            end
512
      endcase
513
   endrule
514
 
515
   // What does this rule do?
516
   rule currMbHorUpdate( !(currMbHor
517
      $display( "TRACE Deblocking Filter: strange update rule firing... %0d", currMb);
518
      Bit#(PicAreaSz) temp = zeroExtend(picWidth);
519
      if((currMbHor >> 3) >= temp)
520
         begin
521
            currMbHor <= currMbHor - (temp << 3);
522
            currMbVer <= currMbVer + 8;
523
         end
524
      else
525
         begin
526
            currMbHor <= currMbHor - temp;
527
            currMbVer <= currMbVer + 1;
528
         end
529
   endrule
530
 
531
 
532
   rule initialize ( process==Initialize && currMbHor
533
      $display( "TRACE Deblocking Filter: initialize %0d", currMb);
534
      process <= Horizontal;
535
      dataReqCount <= 1;
536
      dataRespCount <= 1;
537
      filterTopMbEdgeFlag <= !(currMb
538
      filterLeftMbEdgeFlag <= !(currMbHor==0 || disable_deblocking_filter_idc==1 || (disable_deblocking_filter_idc==2 && currMb==firstMb));
539
      filterInternalEdgesFlag <= !(disable_deblocking_filter_idc==1);
540
      blockNum <= 0;
541
      pixelNum <= 0;
542
      topVectorValidBits <= 0;
543
   endrule
544
 
545
   rule dataSendReq ( dataReqCount>0 && currMbHor
546
      $display( "TRACE Deblocking Filter: dataSendReq %0d", dataReqCount);
547
      Bit#(PicWidthSz) temp = truncate(currMbHor);
548
      if(currMb
549
         dataReqCount <= 0;
550
      else
551
         begin
552
            if(dataReqCount==1)
553
               parameterMemReqQ.enq(LoadReq (temp));
554
            Bit#(4) temp2 = truncate(dataReqCount-1);
555
            let temp3 = {temp,chromaFlag,temp2};
556
            memReqDataSendReq.enq(LoadReq (temp3));
557
            if(dataReqCount==16)
558
               dataReqCount <= 0;
559
            else
560
               dataReqCount <= dataReqCount+1;
561
         end
562
   endrule
563
 
564
 
565
   rule dataReceiveNoResp ( dataRespCount>0 && currMb
566
      $display( "TRACE Deblocking Filter: dataReceiveNoResp");
567
      dataRespCount <= 0;
568
   endrule
569
 
570
   function Action deque(FIFO#(Bit#(32)) fifo);
571
     return fifo.deq();
572
   endfunction
573
 
574
   // rotate column to row major after applying the horizontal filter
575
   rule rowToColumnConversion;
576
     // Check to see if we're even filtering the top edge
577
     Bit#(2) blockVer = {tpl_1(rowToColumnStoreBlock.first())[3],tpl_1(rowToColumnStoreBlock.first())[1]};
578
     Bit#(2) blockHor = {tpl_1(rowToColumnStoreBlock.first())[2],tpl_1(rowToColumnStoreBlock.first())[0]};
579
     Bool storeBottomRightBlock = tpl_2(rowToColumnStoreBlock.first()) == 1;
580
 
581
     rowToColumnState  <= rowToColumnState + 1;
582
     Bit#(32) data_out = 0;
583
     Bit#(PicWidthSz) adjustedMbHor = ((currMbHor==0) ? (picWidth-1) : truncate(currMbHor-1));
584
 
585
     case(rowToColumnState)
586
       2'b00: data_out = {(rowToColumnStore[3].first())[7:0], (rowToColumnStore[2].first())[7:0],
587
                          (rowToColumnStore[1].first())[7:0], (rowToColumnStore[0].first())[7:0]};
588
 
589
       2'b01: data_out = {(rowToColumnStore[3].first())[15:8], (rowToColumnStore[2].first())[15:8],
590
                          (rowToColumnStore[1].first())[15:8], (rowToColumnStore[0].first())[15:8]};
591
 
592
       2'b10: data_out = {(rowToColumnStore[3].first())[23:16], (rowToColumnStore[2].first())[23:16],
593
                          (rowToColumnStore[1].first())[23:16], (rowToColumnStore[0].first())[23:16]};
594
 
595
       2'b11: begin
596
                data_out = {(rowToColumnStore[3].first())[31:24], (rowToColumnStore[2].first())[31:24],
597
                            (rowToColumnStore[1].first())[31:24], (rowToColumnStore[0].first())[31:24]};
598
                mapM_(deque, rowToColumnStore); // Deq the vector elements
599
                rowToColumnStoreBlock.deq();
600
             end
601
       endcase
602
 
603
     if(storeBottomRightBlock) // The right bottom block is not complete until the top filtering has occured
604
                               // It has to be rotated to the column major ordering used in the top vector
605
                               // memory
606
       begin
607
          $display( "TRACE Deblocking Filter: rowToColumnRotate rotating block (%0d, %0d) rowtoColumnState: %d bottomRightBlock: %d, data: %h", blockHor, blockVer, rowToColumnState, storeBottomRightBlock, data_out);
608
         // The block hor calculation may be questionable... between U and V.
609
         if(chromaFlag == 0)
610
           begin
611
             memReqRowToColumnConversion.enq(StoreReq {addr:{adjustedMbHor,chromaFlag,2'b11,rowToColumnState},data:data_out});
612
           end
613
         else
614
           begin  //differentiate between u and v
615
             memReqRowToColumnConversion.enq(StoreReq {addr:{adjustedMbHor,chromaFlag,blockHor[1],1'b1,rowToColumnState},data:data_out});
616
           end
617
 
618
       end
619
     else // pass data along to vertical filter
620
       begin
621
         verticalFilterBlock.enq(tuple2(tpl_1(rowToColumnStoreBlock.first()),data_out));
622
 
623
         $display( "TRACE Deblocking Filter: rowToColumnRotate rotating block (%0d, %0d) rowtoColumnState: %d bottomRightBlock: %d, data: %h", blockHor, blockVer, rowToColumnState, storeBottomRightBlock, data_out);
624
       end
625
   endrule
626
 
627
   // rotate row to column after applying the vertical filter
628
   rule columnToRowConversion;
629
     Bit#(32) data_out = 0;
630
     Bool topValues = tpl_2(columnToRowStoreBlock.first()) == 1;
631
     Bit#(4) blockNumCols = tpl_1(columnToRowStoreBlock.first());
632
     Bit#(2) blockHor = {blockNumCols[2],blockNumCols[0]};
633
     Bit#(2) blockVer = {blockNumCols[3],blockNumCols[1]} - 1; // Subtract 1, because these output values lag slightly
634
     columnToRowState  <= columnToRowState + 1;
635
 
636
     case(columnToRowState)  // not to sure about this ordering
637
       2'b00: data_out = {(columnToRowStore[3].first())[7:0],
638
                          (columnToRowStore[2].first())[7:0],
639
                          (columnToRowStore[1].first())[7:0],
640
                          (columnToRowStore[0].first())[7:0]};
641
 
642
       2'b01: data_out = {(columnToRowStore[3].first())[15:8],
643
                          (columnToRowStore[2].first())[15:8],
644
                          (columnToRowStore[1].first())[15:8],
645
                          (columnToRowStore[0].first())[15:8]};
646
       2'b10: data_out = {(columnToRowStore[3].first())[23:16],
647
                          (columnToRowStore[2].first())[23:16],
648
                          (columnToRowStore[1].first())[23:16],
649
                          (columnToRowStore[0].first())[23:16]};
650
       2'b11: begin
651
                data_out = {(columnToRowStore[3].first())[31:24],
652
                            (columnToRowStore[2].first())[31:24],
653
                            (columnToRowStore[1].first())[31:24],
654
                            (columnToRowStore[0].first())[31:24]};
655
                mapM_(deque, columnToRowStore); // Deq the vector elements
656
                columnToRowStoreBlock.deq();
657
              end
658
     endcase
659
     $write( "TRACE Deblocking Filter: columnToRow rotate block(%0d, %0d) columnToRowState %d, topValues: %d, data: %h", blockHor, blockVer, columnToRowState, topValues, data_out);
660
 
661
     Bit#(PicWidthSz) currMbHorT = truncate(currMbHor);
662
     // Actually send the data out. This stuff is not the bottom row or left column, and is therefore done.
663
     // THe bottom row was sent out to the temporary buffer in the vertical rule.  But if we're on the last row of
664
     // the frame, there coming here.  Also, if we're in the last block, we must output the leftvector values
665
     if( !topValues && (!(blockHor==3 || (blockHor[0]==1 && chromaFlag==1)) || (currMbVer==picHeight-1)))
666
       begin
667
         $display( " Normal");
668
         if(chromaFlag==0)
669
           begin
670
             $display("TRACE mkDeblockFilter: Outputting Luma ver{mbVer, blockVer(2), state}: %h, hor{mbHor, blockHor(2)}: %b, data: %h", {currMbVer,blockVer}, {currMbHorT,blockHor}, data_out);
671
             outfifo.enq(DFBLuma {ver:{currMbVer,blockVer,columnToRowState},
672
                                  hor:{currMbHorT,blockHor},
673
                                  data:data_out});
674
           end
675
         else
676
           begin
677
 $display("TRACE mkDeblockFilter: Outputting Chroma %d ver{mbVer, blockVer(1), state(2)}: %b, hor{mbHor, blockHor(1)}: %b, data: %h",blockHor[1],{currMbVer,blockVer[0],columnToRowState},{currMbHorT,blockHor[0]},data_out);
678
             outfifo.enq(DFBChroma {uv:blockHor[1],
679
                                    ver:{currMbVer,blockVer[0],columnToRowState},
680
                                    hor:{currMbHorT,blockHor[0]},
681
                                    data:data_out});
682
           end
683
       end
684
 
685
     if(topValues)// These are the previous top values, and they must be sent out.  Note, that since this is a past
686
                       // Mb, we must adjust the the Mbs used.
687
       begin
688
         $display( " TopValues");
689
         if(chromaFlag==0)
690
           begin
691
             $display("TRACE mkDeblockFilter: (Top Value) Outputting Luma ver{mbVer, blockVer(2), state(2)}: %b, hor{mbHor, blockHor(2)}: %h, data: %h",{currMbVer-1,2'b11,columnToRowState}, {currMbHorT,blockHor}, data_out);
692
             outfifo.enq(DFBLuma {ver:{currMbVer-1,2'b11,columnToRowState},
693
                                  hor:{currMbHorT,blockHor},
694
                                  data:data_out});
695
           end
696
         else
697
           begin
698
             $display("TRACE mkDeblockFilter: (Top Value) Outputting Chroma %d ver{mbVer, blockVer(1), state(2)}: %b, hor{mbHor, blockHor(1)}: %b, data: %h",blockHor[1],{currMbVer-1,1'b1,columnToRowState},{currMbHorT,blockHor[0]},data_out);
699
             outfifo.enq(DFBChroma {uv:blockHor[1],
700
                                    ver:{currMbVer-1,1'b1,columnToRowState},
701
                                    hor:{currMbHorT,blockHor[0]},
702
                                    data:data_out});
703
           end
704
       end
705
 
706
     if( !topValues && (blockHor==3 || (blockHor[0]==1 && chromaFlag==1))) // We need to write to the left Vector which will be used in the future. These values will not be written out.
707
          // It may be wise at some point to
708
       begin
709
         // We need to check for the last point in the pipeline. This is the bottom right corner of the Mb.
710
         $display( " Left Vector");
711
         if(chromaFlag==0)
712
           begin
713
             if((blockVer == 3) && (columnToRowState == 3))
714
               begin
715
                 process <= Cleanup;
716
               end
717
             //check for last macro block
718
             leftVector.upd({1'b0,blockVer,columnToRowState}, data_out);
719
           end
720
         else
721
           begin
722
             // Only cleanup a single time after the chroma blocks
723
             if((blockHor == 3) && (blockVer[0] == 1) && (columnToRowState == 3))
724
               begin
725
                 process <= Cleanup;
726
               end
727
             leftVector.upd({1'b1,blockHor[1],blockVer[0],columnToRowState}, data_out);
728
           end
729
         end
730
 
731
   endrule
732
 
733
 
734
   rule dataReceiveResp ( dataRespCount>0 && !(currMb
735
      $display( "TRACE Deblocking Filter: dataReceiveResp %0d", dataRespCount);
736
      Bit#(4) temp = truncate(dataRespCount-1);
737
      if(dataRespCount==1)
738
         begin
739
            Bit#(13) tempParameters=0;
740
            if(parameterMemRespQ.first() matches tagged LoadResp .xdata)
741
               tempParameters = xdata;
742
            top_qpy <= tempParameters[5:0];
743
            top_qpc <= tempParameters[11:6];
744
            top_intra <= tempParameters[12];
745
            parameterMemRespQ.deq();
746
         end
747
      if(dataRespCount==16)
748
         dataRespCount <= 0;
749
      else
750
         dataRespCount <= dataRespCount+1;
751
      if(dataMemRespQ.first() matches tagged LoadResp .xdata)
752
        begin
753
          topVectorValidBits[temp] <= 1;
754
          topVector.upd(temp, xdata);
755
        end
756
      dataMemRespQ.deq();
757
      //$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]);
758
   endrule
759
 
760
 
761
   rule horizontal ( process==Horizontal && currMbHor
762
      Bit#(2) blockHor = {blockNum[2],blockNum[0]};
763
      Bit#(2) blockVer = {blockNum[3],blockNum[1]};
764
      Bit#(2) pixelVer = pixelNum;
765
 
766
      Bool leftEdge = (blockNum[0]==0 && (blockNum[2]==0 || chromaFlag==1));
767
      if(blockNum==0 && pixelNum==0)
768
         begin
769
            Bit#(6) qpav = (chromaFlag==0 ? curr_qpy : curr_qpc);
770
            Bit#(8) indexAtemp = zeroExtend(qpav)+signExtend(slice_alpha_c0_offset);
771
            Bit#(8) indexBtemp = zeroExtend(qpav)+signExtend(slice_beta_offset);
772
            Bit#(6) indexA = (indexAtemp[7]==1 ? 0 : (indexAtemp[6:0]>51 ? 51 : indexAtemp[5:0]));
773
            Bit#(6) indexB = (indexBtemp[7]==1 ? 0 : (indexBtemp[6:0]>51 ? 51 : indexBtemp[5:0]));
774
            alphaInternal <= alpha_table[indexA];
775
            betaInternal <= beta_table[indexB];
776
            Vector#(3,Bit#(5)) tc0temp = arrayToVector(tc0_table[indexA]);
777
            tc0Internal <= tc0temp;
778
         end
779
      case (infifo.first()) matches
780
         tagged PBbS .xdata :
781
            begin
782
               infifo.deq();
783
               bSfileHor.upd(blockNum, xdata.bShor);
784
               bSfileVer.upd(blockNum, xdata.bSver);
785
               $display( "TRACE Deblocking Filter: horizontal bsFIFO data: %d, subblock(%0d, %0d) row: %0d, ",infifo.first(), blockHor, blockVer, pixelNum);
786
            end
787
         tagged PBoutput .xdata :
788
            begin
789
               Bit#(PicWidthSz) currMbHorT = truncate(currMbHor);
790
               if((chromaFlag == 1) && (blockHor[1] == 1))
791
                 begin
792
                   $display("PRE %h %h %h", {currMbVer,blockVer[0],pixelVer},{currMbHorT,blockHor[0]}, {xdata[0],xdata[1],xdata[2],xdata[3]});
793
                 end
794
               $display( "TRACE Deblocking Filter: horizontal chroma: %d, subblock(%0d, %0d) row: %0d, data: %h", chromaFlag, blockHor, blockVer, pixelNum, xdata);
795
               infifo.deq();
796
               Bit#(6) addrq = {blockHor,blockVer,pixelVer};
797
               Bit#(5) addrpLeft = (chromaFlag==0 ? {1'b0,blockVer,pixelVer} : {1'b1,blockHor[1],blockVer[0],pixelVer});
798
               Bit#(6) addrpCurr = {(blockHor-1),blockVer,pixelVer};
799
               Bit#(32) pixelq = {xdata[3],xdata[2],xdata[1],xdata[0]};
800
               Bit#(32) pixelp;
801
               if(leftEdge)
802
                 begin
803
                   pixelp <- leftVector.sub(addrpLeft);
804
                   $display( "TRACE Deblocking Filter: horizontal P (left) addr %h, data %h ",addrpLeft, pixelp);
805
                 end
806
               else
807
                 begin
808
                   pixelp <- workVectorRows.sub({blockVer[0], pixelVer});
809
                   $display( "TRACE Deblocking Filter: horizontal P (work) addr %h, data %h ",addrpCurr, pixelp);
810
                 end
811
               Bit#(64) result = {pixelq,pixelp};
812
               if(leftEdge && filterLeftMbEdgeFlag)
813
                  begin
814
                    Bit#(6) curr_qp = (chromaFlag==0 ? curr_qpy : curr_qpc);
815
                    Bit#(6) left_qp = (chromaFlag==0 ? left_qpy : left_qpc);
816
                    Bit#(7) qpavtemp = zeroExtend(curr_qp)+zeroExtend(left_qp)+1;
817
                    Bit#(6) qpav = qpavtemp[6:1];
818
                    Bit#(8) indexAtemp = zeroExtend(qpav)+signExtend(slice_alpha_c0_offset);
819
                    Bit#(8) indexBtemp = zeroExtend(qpav)+signExtend(slice_beta_offset);
820
                    Bit#(6) indexA = (indexAtemp[7]==1 ? 0 : (indexAtemp[6:0]>51 ? 51 : indexAtemp[5:0]));
821
                    Bit#(6) indexB = (indexBtemp[7]==1 ? 0 : (indexBtemp[6:0]>51 ? 51 : indexBtemp[5:0]));
822
                    Bit#(8) alphaMbLeft = alpha_table[indexA];
823
                    Bit#(5) betaMbLeft = beta_table[indexB];
824
                    Vector#(3,Bit#(5)) tc0MbLeft = arrayToVector(tc0_table[indexA]);
825
                    if(filter_test({pixelq[15:0],pixelp[31:16]},alphaMbLeft,betaMbLeft))
826
                      begin
827
                         $display("TRACE mkDeblockFilter: Applying horizontal, left filter");
828
                         Bit#(3) bsData <- bSfileHor.sub((chromaFlag==0?blockNum:{blockNum[1:0],pixelVer[1],1'b0}));
829
                         result = filter_input({pixelq,pixelp},chromaFlag==1,bsData,alphaMbLeft,betaMbLeft,tc0MbLeft);
830
                       end
831
                  end
832
               else if(!leftEdge && filterInternalEdgesFlag)
833
                  begin
834
                     if(filter_test({pixelq[15:0],pixelp[31:16]},alphaInternal,betaInternal))
835
                       begin
836
                         $display("TRACE mkDeblockFilter: Applying horizontal, internal filter");
837
                         Bit#(3) bSData <- bSfileHor.sub((chromaFlag==0?blockNum:{blockNum[1:0],pixelVer[1],1'b0}));
838
                         result = filter_input({pixelq,pixelp},chromaFlag==1,bSData,alphaInternal,betaInternal,tc0Internal);
839
                       end
840
                  end
841
 
842
 
843
               if(leftEdge)
844
                 begin
845
                   // write out the left edge
846
                   //Check to store this value to the memory.  I think the rotation is off here.
847
                   // I should also adjust the vertical Mb...  Figure out MbHorT
848
 
849
                   Bit#(PicHeightSz) adjustedMbVer = ((currMbHorT==0) && (currMbVer!=0)) ? currMbVer-1 : currMbVer;
850
                   Bit#(PicWidthSz)  adjustedMbHor = currMbHorT==0 ? picWidth-1 : currMbHorT-1;
851
                   // In this case we buffer the bottom vertical element, since it has to be used again
852
                   if(((blockVer == 3) || ((chromaFlag == 1) && (blockVer == 1))) && (adjustedMbVer != picHeight - 1))
853
                     begin
854
                       rowToColumnStore[pixelNum[1:0]].enq(result[31:0]);
855
                       // only push in a command for the bottom leftblock.  It has to be rotated.
856
                       if(pixelNum == 3)
857
                         begin
858
                           rowToColumnStoreBlock.enq(tuple2(blockNum,1));
859
                         end
860
                    end
861
                   // these outputs occur in the past, so we must use the adjusted Mb numbers
862
                   else if(chromaFlag==0)
863
                     begin
864
                       $display("TRACE mkDeblockFilter: (Left Vector) Outputting Luma ver{mbVer, blockVer(2), state(2)}: %b, hor{mbHor, blockHor(2)}: %b, data: %h",{adjustedMbVer,blockVer,pixelNum},{adjustedMbHor,2'b11} ,result[31:0] );
865
                       outfifoVertical.enq(DFBLuma {ver:{adjustedMbVer,blockVer,pixelVer},
866
                                            hor:{adjustedMbHor,2'b11},
867
                                            data:result[31:0]});
868
                     end
869
                   else
870
                     begin
871
                       $display("TRACE mkDeblockFilter: (Left Vector) Outputting Chroma %d ver{mbVer, blockVer(2), state(2)}: %b, hor{mbHor, blockHor(2)}: %b, data: %h",blockHor[1],{adjustedMbVer,blockVer[0],pixelNum},{adjustedMbHor,1'b1}  ,result[31:0]);
872
                       outfifoVertical.enq(DFBChroma {uv:blockHor[1],
873
                                              ver:{adjustedMbVer,blockVer[0],pixelVer},
874
                                              hor:{adjustedMbHor,1'b1},
875
                                              data:result[31:0]});
876
                      end
877
                 end
878
               else
879
                  begin
880
                    // push the correction into reorder block;
881
                    rowToColumnStore[addrpCurr[1:0]].enq(result[31:0]);
882
                    // Push down the block number and the chroma flag into the pipeline
883
                    if(pixelNum == 3)
884
                      begin
885
                        let blockHorPast = blockHor - 1;
886
                        let blockNumPast = {blockVer[1], blockHorPast[1], blockVer[0], blockHorPast[0]};
887
                        rowToColumnStoreBlock.enq(tuple2(blockNumPast,0));
888
                      end
889
                  end
890
               $display( "TRACE Deblocking Filter: horizontal Q (work) addr %h, data %h, original data: %h ",addrq, result[63:32], pixelq);
891
               workVectorRows.upd({blockVer[0],pixelVer}, result[63:32]);
892
 
893
               // Step out to clean up the edge block
894
               // What about the chroma?
895
               if((pixelNum == 3) && ((blockHor == 3) || ((chromaFlag == 1) && (blockHor == 1))))
896
                 begin
897
                    $display( "TRACE Deblocking Filter: Heading to Horizontal Cleanup");
898
                   process <= HorizontalCleanup;// we enter this state to push out the remaining
899
                                                  // blocks, that haven't been shoved out.  Namely, the
900
                                                  // left blocks.
901
                 end
902
               else if(pixelNum==3)
903
                 begin
904
                   $display( "TRACE Deblocking Filter: horizontal bsFIFO completed subblock(%0d, %0d)", blockHor, blockVer);
905
                   blockNum <= blockNum+1;
906
                 end
907
               pixelNum <= pixelNum+1;
908
            end
909
         default: $display( "ERROR Deblocking Filter: horizontal non-PBoutput input");
910
      endcase
911
   endrule
912
 
913
  rule horizontal_cleanup(process == HorizontalCleanup);
914
    Bit#(2) blockHor = {blockNum[2],blockNum[0]};
915
    Bit#(2) blockVer = {blockNum[3],blockNum[1]};
916
    $display( "TRACE Deblocking Filter: horizontal_cleanup (%0d, %0d) row: %d", blockHor, blockVer, pixelNum);
917
    if(pixelNum==3 && (blockNum==15 || (blockNum==7 && chromaFlag==1)))
918
      begin
919
        if(blockNum == 15)
920
          begin
921
            $display( "TRACE Deblocking Filter: horizontal completed Mb (%0d) Luma", currMb);
922
          end
923
        else
924
          begin
925
            $display( "TRACE Deblocking Filter: horizontal completed Mb (%0d) Chroma", currMb);
926
          end
927
        blockNum <= 0;
928
        process <= Vertical;// we enter this state to wait for the vertical processing to complete
929
        rowToColumnStoreBlock.enq(tuple2(blockNum,0));
930
      end
931
    else if(pixelNum == 3)
932
      begin
933
        blockNum <= blockNum + 1;
934
        process <= Horizontal; // not done with this Mb yet.
935
        rowToColumnStoreBlock.enq(tuple2(blockNum,0));
936
      end
937
    pixelNum <= pixelNum + 1;
938
    // push the correction into reorder block;
939
    Bit#(32) work_data <- workVectorRows.sub({blockVer[0], pixelNum});
940
    rowToColumnStore[pixelNum].enq(work_data);
941
  endrule
942
 
943
 
944
  // declare these to share the rule
945
  begin
946
   Bit#(4) blockNumCols = tpl_1(verticalFilterBlock.first());
947
   Bit#(2) blockVer = {blockNumCols[3],blockNumCols[1]};
948
   Bit#(2) blockHor = {blockNumCols[2],blockNumCols[0]};
949
   Bool topEdge = (blockVer==0);
950
 
951
 
952
  rule vertical_filter_halt((verticalState == NormalOperation) && !((!topEdge) || (topVectorValidBits[{blockHor,columnNumber}] == 1) || (currMb
953
        if(process == Vertical || process == Horizontal)
954
          begin
955
            $display("TRACE Deblocking Filter: Vertical processing halted on block: %h (%0d, %0d), column %d chromaFlag %d due to data dependency",  blockNumCols, blockHor, blockVer, columnNumber, chromaFlag);
956
          end
957
 
958
  endrule
959
 
960
 
961
  // As with horizontal, the q data will be read from the data store, and the p data will be streamed in via the
962
  // reordering FIFO.  The new p data must be stored, but the q data will need to be spooled out, since it needs to
963
  // make it to the left vector.
964
  rule vertical((verticalState == NormalOperation) && ((!topEdge) || (topVectorValidBits[{blockHor,columnNumber}] == 1) || (currMb
965
    //$display( "TRACE Deblocking Filter: vertical %0d %0d", colNum, rowNum);
966
    //$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]);
967
    //Process the block according to what got passed to us.
968
    Bit#(32) workV = tpl_2(verticalFilterBlock.first());
969
    Bit#(32) tempV = 0;
970
    Bit#(64) resultV = 0;
971
    Bit#(8) alpha;
972
    Bit#(5) beta;
973
    Vector#(3,Bit#(5)) tc0;
974
 
975
 
976
      $display( "TRACE Deblocking Filter: vertical subblock (%0d, %0d), column: %d, data: %h", blockHor, blockVer, columnNumber, workV);
977
      columnNumber <= columnNumber + 1;
978
      verticalFilterBlock.deq();
979
      if(topEdge)
980
         begin
981
            Bit#(6) curr_qp = (chromaFlag==0 ? curr_qpy : curr_qpc);
982
            Bit#(6) top_qp = (chromaFlag==0 ? top_qpy : top_qpc);
983
            Bit#(7) qpavtemp = zeroExtend(curr_qp)+zeroExtend(top_qp)+1;
984
            Bit#(6) qpav = qpavtemp[6:1];
985
            Bit#(8) indexAtemp = zeroExtend(qpav)+signExtend(slice_alpha_c0_offset);
986
            Bit#(8) indexBtemp = zeroExtend(qpav)+signExtend(slice_beta_offset);
987
            Bit#(6) indexA = (indexAtemp[7]==1 ? 0 : (indexAtemp[6:0]>51 ? 51 : indexAtemp[5:0]));
988
            Bit#(6) indexB = (indexBtemp[7]==1 ? 0 : (indexBtemp[6:0]>51 ? 51 : indexBtemp[5:0]));
989
            Bit#(8) alphaMbTop = alpha_table[indexA];
990
            Bit#(5) betaMbTop = beta_table[indexB];
991
            Vector#(3,Bit#(5)) tc0MbTop = arrayToVector(tc0_table[indexA]);
992
            tempV <- topVector.sub({blockHor,columnNumber});
993
            $display( "TRACE Deblocking Filter: vertical P (top) addr %h, orig data %h ",{blockVer,columnNumber}, tempV);
994
            alpha = alphaMbTop;
995
            beta = betaMbTop;
996
            tc0 = tc0MbTop;
997
         end
998
      else
999
         begin
1000
            // We read this value from the original vector
1001
            tempV <- topVector.sub({blockHor, columnNumber});
1002
            $display( "TRACE Deblocking Filter: vertical P (work) addr %h, orig data %h ",{blockHor, blockVer - 1, columnNumber}, tempV);
1003
            alpha = alphaInternal;
1004
            beta = betaInternal;
1005
            tc0 = tc0Internal;
1006
         end
1007
 
1008
      // Marshalling data in things upon which the filter blocks can be applied
1009
 
1010
      resultV = {tpl_2(verticalFilterBlock.first()),tempV};
1011
 
1012
      // Apply filter, only if filter test passes, and we are either filtering the top edge, or we aren't on the top edge
1013
      $display( "TRACE Deblocking Filter: vertical Filter test: P1P0Q0Q1: %h",{workV[15:8],workV[7:0],tempV[31:24],tempV[23:16]});
1014
      if((filter_test({workV[15:8],workV[7:0],tempV[31:24],tempV[23:16]},alpha,beta)) && ((topEdge && filterTopMbEdgeFlag)|| (!topEdge && filterInternalEdgesFlag) ))
1015
        begin
1016
          $display("TRACE mkDeblockFilter: Applying vertical filter");
1017
          Bit#(3) bsData <- bSfileVer.sub((chromaFlag==0?blockNumCols:{blockVer[0],blockHor[0],1'b0,columnNumber[1]}));
1018
          resultV = filter_input(resultV,chromaFlag==1,bsData,alpha,beta,tc0);
1019
        end
1020
      //Write out the result data  31:0 are the done q values
1021
      if(topEdge)
1022
         begin
1023
            // We really need to just output these values -> need to shove them to the rotation unit, but only if the
1024
            // current Mb vertical component is larger than 0.  All of these are done and can be dumped out
1025
            if(currMbVer > 0)
1026
              begin
1027
                if(columnNumber == 3)
1028
                  begin
1029
                    columnToRowStoreBlock.enq(tuple2(blockNumCols,1'b1));
1030
                  end
1031
                columnToRowStore[columnNumber].enq(resultV[31:0]);
1032
              end
1033
         end
1034
      else
1035
         begin
1036
            // We should make the decision as to whether to store these values. We will store the bottom row, except
1037
            // for the left most block which will be stored the next time that an Mb gets processed.
1038
            // The values to store are in the P vector... except the bottom right block, which is different.
1039
            Bit#(PicWidthSz) currMbHorT = truncate(currMbHor);
1040
 
1041
            if(((blockVer == 3) && (blockHor == 3)) || ((chromaFlag == 1) && (blockVer == 1) && (blockHor[0] == 1)))
1042
              begin
1043
                // need to enter escape state to write the bottom left block to the leftVector.
1044
                if(columnNumber == 3)
1045
                  begin
1046
                    blockHorVerticalCleanup <= blockHor;
1047
                    verticalState <= VerticalCleanup;
1048
                  end
1049
              end
1050
            else if((blockVer == 3) || ((chromaFlag == 1) && (blockVer == 1)))
1051
              begin
1052
                if((currMbVer == picHeight - 1) && (columnNumber == 3)) // If we're at the bottom of the frame, we'd
1053
                                                                        // roll through the block clean up.
1054
                  begin
1055
                    blockHorVerticalCleanup <= blockHor;
1056
                    verticalState <= VerticalCleanup;
1057
                  end
1058
                memReqVertical.enq(StoreReq {addr:{currMbHorT,chromaFlag,blockHor,columnNumber},data:resultV[63:32]});
1059
              end
1060
            columnToRowStore[columnNumber].enq(resultV[31:0]);
1061
            if(columnNumber == 0)
1062
              begin
1063
                columnToRowStoreBlock.enq(tuple2(blockNumCols,1'b0));
1064
              end
1065
         end
1066
 
1067
        $display( "TRACE Deblocking Filter: vertical P                 data %h                     ",  resultV[31:0]);
1068
        $display( "TRACE Deblocking Filter: vertical Q (work) addr %h, data %h, original data: %h  ",{blockHor,blockVer,columnNumber}, resultV[63:32], workV);
1069
 
1070
        topVector.upd({blockHor,columnNumber}, resultV[63:32]);
1071
  endrule
1072
end
1073
 
1074
  rule vertical_cleanup(verticalState == VerticalCleanup);
1075
    $display( "TRACE Deblocking Filter: vertical_cleanup at block end column: %d ", columnNumber);
1076
    columnNumber <= columnNumber + 1;
1077
    if(columnNumber == 3)
1078
      begin
1079
        verticalState <= NormalOperation;
1080
      end
1081
    if(chromaFlag == 0)
1082
      begin
1083
        Bit#(2) blockHor = blockHorVerticalCleanup;
1084
        Bit#(2) blockVer = 0;
1085
        if(columnNumber == 3)
1086
          begin
1087
            // Horizontal Postion is 3, but vertical position is 0, owing to subtraction in the rotation unit
1088
            columnToRowStoreBlock.enq(tuple2({blockVer[1],blockHor[1],blockVer[0],blockHor[0]},1'b0));
1089
          end
1090
        Bit#(32) w_data <- topVector.sub({blockHor, columnNumber});
1091
        columnToRowStore[columnNumber].enq(w_data);
1092
     end
1093
   else
1094
     begin
1095
       Bit#(2) blockHor = blockHorVerticalCleanup;
1096
       Bit#(2) blockVer = 2; // need to make this two for subtraction in rotation unit
1097
       if(columnNumber == 3)
1098
         begin
1099
           // Horizontal Postion is 3, but vertical position is 0, owing to subtraction in the rotation unit
1100
           columnToRowStoreBlock.enq(tuple2({blockVer[1],blockHor[1],blockVer[0],blockHor[0]},1'b0));
1101
         end
1102
       Bit#(32) w_data <- topVector.sub({blockHor, columnNumber});
1103
       columnToRowStore[columnNumber].enq(w_data);
1104
     end
1105
  endrule
1106
 
1107
 
1108
  rule cleanup ( process==Cleanup && currMbHor
1109
    $display( "TRACE Deblocking Filter: cleanup %0d", currMb);
1110
    Bit#(PicWidthSz) currMbHorT = truncate(currMbHor);
1111
    if(chromaFlag==0)
1112
      begin
1113
        chromaFlag <= 1;
1114
        process <= Initialize;
1115
        $display( "TRACE Deblocking Filter: horizontal bsFIFO luma completed");
1116
      end
1117
    else
1118
      begin
1119
        $display( "TRACE Deblocking Filter: horizontal bsFIFO chroma completed");
1120
        chromaFlag <= 0;
1121
        process <= Passing;
1122
        Bit#(PicWidthSz) temp = truncate(currMbHor);
1123
        parameterMemReqQ.enq(StoreReq {addr:temp,data:{curr_intra,curr_qpc,curr_qpy}});
1124
        left_intra <= curr_intra;
1125
        left_qpc <= curr_qpc;
1126
        left_qpy <= curr_qpy;
1127
        currMb <= currMb+1;
1128
        currMbHor <= currMbHor+1;
1129
        if(currMbVer==picHeight-1 && currMbHor==zeroExtend(picWidth-1))
1130
          begin
1131
            outfifo.enq(EndOfFrame);
1132
          end
1133
      end
1134
   endrule
1135
 
1136
   interface Client mem_client_data;
1137
      interface Get request  = fifoToGet(dataMemReqQ);
1138
      interface Put response = fifoToPut(dataMemRespQ);
1139
   endinterface
1140
 
1141
   interface Client mem_client_parameter;
1142
      interface Get request  = fifoToGet(parameterMemReqQ);
1143
      interface Put response = fifoToPut(parameterMemRespQ);
1144
   endinterface
1145
 
1146
   interface Put ioin  = fifoToPut(fifofToFifo(infifo));
1147
   interface Get ioout = fifoToGet(outfifo);
1148
 
1149
endmodule
1150
 
1151
endpackage

powered by: WebSVN 2.1.0

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