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 100

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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