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

Subversion Repositories bluespec-h264

[/] [bluespec-h264/] [trunk/] [release/] [mkInterpolator_3stage.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
// interpolator implementation
3
//----------------------------------------------------------------------
4
//
5
//
6
 
7
package mkInterpolator;
8
 
9
import H264Types::*;
10
import IInterpolator::*;
11
import FIFO::*;
12
import Vector::*;
13
 
14
import Connectable::*;
15
import GetPut::*;
16
import ClientServer::*;
17
 
18
 
19
//-----------------------------------------------------------
20
// Local Datatypes
21
//-----------------------------------------------------------
22
 
23
typedef union tagged
24
{
25
 struct { Bit#(2) xFracL; Bit#(2) yFracL; Bit#(2) offset; IPBlockType bt; } IPWLuma;
26
 struct { Bit#(3) xFracC; Bit#(3) yFracC; Bit#(2) offset; IPBlockType bt; } IPWChroma;
27
}
28
InterpolatorWT deriving(Eq,Bits);
29
 
30
 
31
//-----------------------------------------------------------
32
// Helper functions
33
 
34
function Bit#(8) clip1y10to8( Bit#(10) innum );
35
   if(innum[9] == 1)
36
      return 0;
37
   else if(innum[8] == 1)
38
      return 255;
39
   else
40
      return truncate(innum);
41
endfunction
42
 
43
function Bit#(15) interpolate8to15( Bit#(8) in0, Bit#(8) in1, Bit#(8) in2, Bit#(8) in3, Bit#(8) in4, Bit#(8) in5 );
44
   return zeroExtend(in0) - 5*zeroExtend(in1) + 20*zeroExtend(in2) + 20*zeroExtend(in3) - 5*zeroExtend(in4) + zeroExtend(in5);
45
endfunction
46
 
47
function Bit#(8) interpolate15to8( Bit#(15) in0, Bit#(15) in1, Bit#(15) in2, Bit#(15) in3, Bit#(15) in4, Bit#(15) in5 );
48
   Bit#(20) temp = signExtend(in0) - 5*signExtend(in1) + 20*signExtend(in2) + 20*signExtend(in3) - 5*signExtend(in4) + signExtend(in5) + 512;
49
   return clip1y10to8(truncate(temp>>10));
50
endfunction
51
 
52
 
53
 
54
//-----------------------------------------------------------
55
// Interpolation Module
56
//-----------------------------------------------------------
57
 
58
 
59
(* synthesize *)
60
module mkInterpolator( Interpolator );
61
 
62
   FIFO#(InterpolatorIT) reqfifoLoad <- mkSizedFIFO(interpolator_reqfifoLoad_size);
63
   FIFO#(InterpolatorWT) reqfifoWork <- mkSizedFIFO(interpolator_reqfifoWork_size);
64
   FIFO#(Vector#(4,Bit#(8))) outfifo <- mkFIFO;
65
   Reg#(Bool) endOfFrameFlag <- mkReg(False);
66
   FIFO#(InterpolatorLoadReq)  memReqQ  <- mkFIFO;
67
   FIFO#(InterpolatorLoadResp) memRespQ <- mkSizedFIFO(interpolator_memRespQ_size);
68
 
69
   Reg#(Bit#(PicWidthSz))  picWidth  <- mkReg(maxPicWidthInMB);
70
   Reg#(Bit#(PicHeightSz)) picHeight <- mkReg(0);
71
 
72
   RFile1#(Bit#(5),Vector#(4,Bit#(15))) workFile  <- mkRFile1Full();
73
   RFile1#(Bit#(4),Vector#(4,Bit#(8))) resultFile <- mkRFile1Full();
74
 
75
   Reg#(Bit#(1)) loadStage  <- mkReg(0);
76
   Reg#(Bit#(2)) loadHorNum <- mkReg(0);
77
   Reg#(Bit#(4)) loadVerNum <- mkReg(0);
78
 
79
   Reg#(Bit#(1)) workStage     <- mkReg(0);
80
   Reg#(Bit#(2)) workMbPart    <- mkReg(0);//only for Chroma
81
   Reg#(Bit#(2)) workSubMbPart <- mkReg(0);
82
   Reg#(Bit#(2)) workHorNum    <- mkReg(0);
83
   Reg#(Bit#(4)) workVerNum    <- mkReg(0);
84
   Reg#(Vector#(20,Bit#(8))) workVector8 <- mkRegU;
85
   Reg#(Vector#(20,Bit#(15))) workVector15 <- mkRegU;
86
   Reg#(Vector#(4,Bit#(1))) resultReady <- mkRegU;
87
   Reg#(Bool) workDone <- mkReg(False);
88
 
89
   Reg#(Bit#(2)) outBlockNum <- mkReg(0);
90
   Reg#(Bit#(2)) outPixelNum <- mkReg(0);
91
   Reg#(Bool) outDone <- mkReg(False);
92
 
93
 
94
   rule sendEndOfFrameReq( endOfFrameFlag );
95
      endOfFrameFlag <= False;
96
      memReqQ.enq(IPLoadEndFrame);
97
   endrule
98
 
99
 
100
   rule loadLuma( reqfifoLoad.first() matches tagged IPLuma .reqdata &&& !endOfFrameFlag );
101
      Bit#(2) xfracl = reqdata.mvhor[1:0];
102
      Bit#(2) yfracl = reqdata.mvver[1:0];
103
      Bool twoStage = (xfracl==1||xfracl==3) && (yfracl==1||yfracl==3);
104
      Bool horInter = (twoStage ? loadStage==1 : xfracl!=0);
105
      Bool verInter = (twoStage ? loadStage==0 : yfracl!=0);
106
      Bit#(2) offset = reqdata.mvhor[3:2] + ((twoStage&&verInter&&xfracl==3) ? 1 : 0);
107
      Bit#(1) horOut = 0;
108
      Bit#(TAdd#(PicWidthSz,2)) horAddr;
109
      Bit#(TAdd#(PicHeightSz,4)) verAddr;
110
      Bit#(TAdd#(PicWidthSz,12)) horTemp = zeroExtend({reqdata.hor,2'b00}) + zeroExtend({loadHorNum,2'b00}) + (xfracl==3&&(yfracl==1||yfracl==3)&&loadStage==0 ? 1 : 0);
111
      Bit#(TAdd#(PicHeightSz,10)) verTemp = zeroExtend(reqdata.ver) + zeroExtend(loadVerNum) + (yfracl==3&&(xfracl==1||xfracl==3)&&loadStage==1 ? 1 : 0);
112
      Bit#(13) mvhortemp = signExtend(reqdata.mvhor[13:2])-(horInter?2:0);
113
      Bit#(11) mvvertemp = signExtend(reqdata.mvver[11:2])-(verInter?2:0);
114
      if(mvhortemp[12]==1 && zeroExtend(0-mvhortemp)>horTemp)
115
         begin
116
            horAddr = 0;
117
            horOut = 1;
118
         end
119
      else
120
         begin
121
            horTemp = horTemp + signExtend(mvhortemp);
122
            if(horTemp>=zeroExtend({picWidth,4'b0000}))
123
               begin
124
                  horAddr = {picWidth-1,2'b11};
125
                  horOut = 1;
126
               end
127
            else
128
               horAddr = truncate(horTemp>>2);
129
         end
130
      if(mvvertemp[10]==1 && zeroExtend(0-mvvertemp)>verTemp)
131
         verAddr = 0;
132
      else
133
         begin
134
            verTemp = verTemp + signExtend(mvvertemp);
135
            if(verTemp>=zeroExtend({picHeight,4'b0000}))
136
               verAddr = {picHeight-1,4'b1111};
137
            else
138
               verAddr = truncate(verTemp);
139
         end
140
      memReqQ.enq(IPLoadLuma {refIdx:reqdata.refIdx,horOutOfBounds:horOut,hor:horAddr,ver:verAddr});
141
      Bool verFirst = (twoStage&&loadStage==0) || (yfracl==2&&(xfracl==1||xfracl==3));
142
      Bit#(2) loadHorNumMax = (reqdata.bt==IP8x8||reqdata.bt==IP8x4 ? 1 : 0) + (horInter ? 2 : (offset==0 ? 0 : 1));
143
      Bit#(4) loadVerNumMax = (reqdata.bt==IP8x8||reqdata.bt==IP4x8 ? 7 : 3) + (verInter ? 5 : 0);
144
      if(verFirst)
145
         begin
146
            if(loadVerNum < loadVerNumMax)
147
               loadVerNum <= loadVerNum+1;
148
            else
149
               begin
150
                  loadVerNum <= 0;
151
                  if(loadHorNum < loadHorNumMax)
152
                     loadHorNum <= loadHorNum+1;
153
                  else
154
                     begin
155
                        loadHorNum <= 0;
156
                        if(twoStage)
157
                           loadStage <= 1;
158
                        else
159
                           reqfifoLoad.deq();
160
                     end
161
               end
162
         end
163
      else
164
         begin
165
            if(loadHorNum < loadHorNumMax)
166
               loadHorNum <= loadHorNum+1;
167
            else
168
               begin
169
                  loadHorNum <= 0;
170
                  if(loadVerNum < loadVerNumMax)
171
                     loadVerNum <= loadVerNum+1;
172
                  else
173
                     begin
174
                        loadVerNum <= 0;
175
                        loadStage <= 0;
176
                        reqfifoLoad.deq();
177
                     end
178
               end
179
         end
180
      if(reqdata.bt==IP16x16 || reqdata.bt==IP16x8 || reqdata.bt==IP8x16)
181
         $display( "ERROR Interpolation: loadLuma block sizes > 8x8 not supported");
182
      //$display( "Trace interpolator: loadLuma %h %h %h %h %h %h %h", xfracl, yfracl, loadHorNum, loadVerNum, reqdata.refIdx, horAddr, verAddr);
183
   endrule
184
 
185
 
186
   rule loadChroma( reqfifoLoad.first() matches tagged IPChroma .reqdata &&& !endOfFrameFlag );
187
      Bit#(3) xfracc = reqdata.mvhor[2:0];
188
      Bit#(3) yfracc = reqdata.mvver[2:0];
189
      Bit#(2) offset = reqdata.mvhor[4:3]+{reqdata.hor[0],1'b0};
190
      Bit#(1) horOut = 0;
191
      Bit#(TAdd#(PicWidthSz,1)) horAddr;
192
      Bit#(TAdd#(PicHeightSz,3)) verAddr;
193
      Bit#(TAdd#(PicWidthSz,11)) horTemp = zeroExtend({reqdata.hor,1'b0}) + zeroExtend({loadHorNum,2'b00});
194
      Bit#(TAdd#(PicHeightSz,9)) verTemp = zeroExtend(reqdata.ver) + zeroExtend(loadVerNum);
195
      if(reqdata.mvhor[13]==1 && zeroExtend(0-reqdata.mvhor[13:3])>horTemp)
196
         begin
197
            horAddr = 0;
198
            horOut = 1;
199
         end
200
      else
201
         begin
202
            horTemp = horTemp + signExtend(reqdata.mvhor[13:3]);
203
            if(horTemp>=zeroExtend({picWidth,3'b000}))
204
               begin
205
                  horAddr = {picWidth-1,1'b1};
206
                  horOut = 1;
207
               end
208
            else
209
               horAddr = truncate(horTemp>>2);
210
         end
211
      if(reqdata.mvver[11]==1 && zeroExtend(0-reqdata.mvver[11:3])>verTemp)
212
         verAddr = 0;
213
      else
214
         begin
215
            verTemp = verTemp + signExtend(reqdata.mvver[11:3]);
216
            if(verTemp>=zeroExtend({picHeight,3'b000}))
217
               verAddr = {picHeight-1,3'b111};
218
            else
219
               verAddr = truncate(verTemp);
220
         end
221
      memReqQ.enq(IPLoadChroma {refIdx:reqdata.refIdx,uv:reqdata.uv,horOutOfBounds:horOut,hor:horAddr,ver:verAddr});
222
      Bit#(2) loadHorNumMax = (reqdata.bt==IP4x8||reqdata.bt==IP4x4 ? (offset[1]==0||(xfracc==0&&offset!=3) ? 0 : 1) : ((reqdata.bt==IP16x16||reqdata.bt==IP16x8 ? 1 : 0) + (xfracc==0&&offset==0 ? 0 : 1)));
223
      Bit#(4) loadVerNumMax = (reqdata.bt==IP16x16||reqdata.bt==IP8x16 ? 7 : (reqdata.bt==IP16x8||reqdata.bt==IP8x8||reqdata.bt==IP4x8 ? 3 : 1)) + (yfracc==0 ? 0 : 1);
224
      if(loadHorNum < loadHorNumMax)
225
         loadHorNum <= loadHorNum+1;
226
      else
227
         begin
228
            loadHorNum <= 0;
229
            if(loadVerNum < loadVerNumMax)
230
               loadVerNum <= loadVerNum+1;
231
            else
232
               begin
233
                  loadVerNum <= 0;
234
                  reqfifoLoad.deq();
235
               end
236
         end
237
      //$display( "Trace interpolator: loadChroma %h %h %h %h %h %h %h", xfracc, yfracc, loadHorNum, loadVerNum, reqdata.refIdx, horAddr, verAddr);
238
   endrule
239
 
240
 
241
   rule workLuma ( reqfifoWork.first() matches tagged IPWLuma .reqdata &&& !workDone );
242
      let xfracl = reqdata.xFracL;
243
      let yfracl = reqdata.yFracL;
244
      let offset = reqdata.offset;
245
      let blockT = reqdata.bt;
246
      Vector#(20,Bit#(8)) workVector8Next = workVector8;
247
      Vector#(20,Bit#(15)) workVector15Next = workVector15;
248
      Vector#(4,Bit#(1)) resultReadyNext = resultReady;
249
      if(workStage == 0)
250
         begin
251
            if(memRespQ.first() matches tagged IPLoadResp .tempreaddata)
252
               begin
253
                  memRespQ.deq();
254
                  Vector#(4,Bit#(8)) readdata = replicate(0);
255
                  readdata[0] = tempreaddata[7:0];
256
                  readdata[1] = tempreaddata[15:8];
257
                  readdata[2] = tempreaddata[23:16];
258
                  readdata[3] = tempreaddata[31:24];
259
                  //$display( "Trace interpolator: workLuma stage 0 readdata %h %h %h %h %h %h", workHorNum, workVerNum, readdata[3], readdata[2], readdata[1], readdata[0] );
260
                  Vector#(4,Bit#(8)) tempResult8 = replicate(0);
261
                  Vector#(4,Bit#(15)) tempResult15 = replicate(0);
262
                  if(xfracl==0 || yfracl==0 || xfracl==2)
263
                     begin
264
                        if(xfracl==0)//reorder
265
                           begin
266
                              for(Integer ii=0; ii<4; ii=ii+1)
267
                                 begin
268
                                    Bit#(2) offsetplusii = offset+fromInteger(ii);
269
                                    if(offset <= 3-fromInteger(ii) && offset!=0)
270
                                       tempResult8[ii] = workVector8[offsetplusii];
271
                                    else
272
                                       tempResult8[ii] = readdata[offsetplusii];
273
                                    workVector8Next[ii] = readdata[ii];
274
                                 end
275
                              for(Integer ii=0; ii<4; ii=ii+1)
276
                                 tempResult15[ii] = zeroExtend({tempResult8[ii],5'b00000});
277
                           end
278
                        else//horizontal interpolation
279
                           begin
280
                              offset = offset-2;
281
                              for(Integer ii=0; ii<8; ii=ii+1)
282
                                 workVector8Next[ii] = workVector8[ii+4];
283
                              for(Integer ii=0; ii<4; ii=ii+1)
284
                                 begin
285
                                    Bit#(4) tempIndex = fromInteger(ii) + 8 - zeroExtend(offset);
286
                                    workVector8Next[tempIndex] = readdata[ii];
287
                                 end
288
                              for(Integer ii=0; ii<4; ii=ii+1)
289
                                 begin
290
                                    tempResult15[ii] = interpolate8to15(workVector8Next[ii],workVector8Next[ii+1],workVector8Next[ii+2],workVector8Next[ii+3],workVector8Next[ii+4],workVector8Next[ii+5]);
291
                                    tempResult8[ii] = clip1y10to8(truncate((tempResult15[ii]+16)>>5));
292
                                    if(xfracl == 1)
293
                                       tempResult8[ii] = truncate(({1'b0,tempResult8[ii]} + {1'b0,workVector8Next[ii+2]} + 1) >> 1);
294
                                    else if(xfracl == 3)
295
                                       tempResult8[ii] = truncate(({1'b0,tempResult8[ii]} + {1'b0,workVector8Next[ii+3]} + 1) >> 1);
296
                                 end
297
                           end
298
                        Bit#(2) workHorNumOffset = (xfracl!=0 ? 2 : (reqdata.offset==0 ? 0 : 1));
299
                        if(workHorNum >= workHorNumOffset)
300
                           begin
301
                              Bit#(1) horAddr = truncate(workHorNum-workHorNumOffset);
302
                              if(yfracl == 0)//write to resultFile
303
                                 begin
304
                                    Bit#(3) verAddr = truncate(workVerNum);
305
                                    horAddr = horAddr + ((blockT==IP4x8&&workSubMbPart==1)||(blockT==IP4x4&&workSubMbPart[0]==1) ? 1 : 0);
306
                                    verAddr = verAddr + ((blockT==IP8x4&&workSubMbPart==1)||(blockT==IP4x4&&workSubMbPart[1]==1) ? 4 : 0);
307
                                    resultFile.upd({verAddr,horAddr},tempResult8);
308
                                    if(verAddr[1:0] == 3)
309
                                       resultReadyNext[{verAddr[2],horAddr}] = 1;
310
                                 end
311
                              else//write to workFile
312
                                 workFile.upd({workVerNum,horAddr},tempResult15);
313
                           end
314
                        Bit#(2) workHorNumMax = (blockT==IP8x8||blockT==IP8x4 ? 1 : 0) + workHorNumOffset;
315
                        Bit#(4) workVerNumMax = (blockT==IP8x8||blockT==IP4x8 ? 7 : 3) + (yfracl!=0 ? 5 : 0);
316
                        if(workHorNum < workHorNumMax)
317
                           workHorNum <= workHorNum+1;
318
                        else
319
                           begin
320
                              workHorNum <= 0;
321
                              if(workVerNum < workVerNumMax)
322
                                 workVerNum <= workVerNum+1;
323
                              else
324
                                 begin
325
                                    workVerNum <= 0;
326
                                    if(yfracl!=0)
327
                                       workStage <= 1;
328
                                    else
329
                                       begin
330
                                          if(((blockT==IP4x8 || blockT==IP8x4) && workSubMbPart==0) || (blockT==IP4x4 && workSubMbPart<3))
331
                                             workSubMbPart <= workSubMbPart+1;
332
                                          else
333
                                             begin
334
                                                workSubMbPart <= 0;
335
                                                workDone <= True;
336
                                             end
337
                                          reqfifoWork.deq();
338
                                       end
339
                                 end
340
                           end
341
                     end
342
                  else//vertical interpolation
343
                     begin
344
                        offset = offset + (xfracl==3&&(yfracl==1||yfracl==3) ? 1 : 0);
345
                        for(Integer ii=0; ii<4; ii=ii+1)
346
                           tempResult15[ii] = interpolate8to15(workVector8[ii],workVector8[ii+4],workVector8[ii+8],workVector8[ii+12],workVector8[ii+16],readdata[ii]);
347
                        for(Integer ii=0; ii<16; ii=ii+1)
348
                           workVector8Next[ii] = workVector8[ii+4];
349
                        for(Integer ii=0; ii<4; ii=ii+1)
350
                           workVector8Next[ii+16] = readdata[ii];
351
                        Bit#(2) workHorNumMax = (blockT==IP8x8||blockT==IP8x4 ? 1 : 0) + (yfracl==2 ? 2 : (offset==0 ? 0 : 1));
352
                        Bit#(4) workVerNumMax = (blockT==IP8x8||blockT==IP4x8 ? 7 : 3) + 5;
353
                        Bit#(2) horAddr = workHorNum;
354
                        Bit#(3) verAddr = truncate(workVerNum-5);
355
                        if(workVerNum > 4)
356
                           begin
357
                              workFile.upd({verAddr,horAddr},tempResult15);
358
                              //$display( "Trace interpolator: workLuma stage 0 result %h %h %h %h %h %h %h", workHorNum, workVerNum, {verAddr,horAddr}, tempResult15[3], tempResult15[2], tempResult15[1], tempResult15[0]);
359
                           end
360
                        if(workVerNum < workVerNumMax)
361
                           workVerNum <= workVerNum+1;
362
                        else
363
                           begin
364
                              workVerNum <= 0;
365
                              if(workHorNum < workHorNumMax)
366
                                 workHorNum <= workHorNum+1;
367
                              else
368
                                 begin
369
                                    workHorNum <= 0;
370
                                    workStage <= 1;
371
                                 end
372
                           end
373
                     end
374
               end
375
         end
376
      else
377
         begin
378
            Vector#(4,Bit#(8)) tempResult8 = replicate(0);
379
            Vector#(4,Bit#(15)) readdata = replicate(0);
380
            if(yfracl==0)
381
               $display( "ERROR Interpolation: workLuma loadStage==1 and yfracl==0");
382
            if(xfracl==0 || xfracl==2)//vertical interpolation
383
               begin
384
                  readdata = workFile.sub({workVerNum,workHorNum[0]});
385
                  for(Integer ii=0; ii<4; ii=ii+1)
386
                     begin
387
                        tempResult8[ii] = interpolate15to8(workVector15[ii],workVector15[ii+4],workVector15[ii+8],workVector15[ii+12],workVector15[ii+16],readdata[ii]);
388
                        if(yfracl == 1)
389
                           tempResult8[ii] = truncate(({1'b0,tempResult8[ii]} + {1'b0,clip1y10to8(truncate((workVector15[ii+8]+16)>>5))} + 1) >> 1);
390
                        else if(yfracl == 3)
391
                           tempResult8[ii] = truncate(({1'b0,tempResult8[ii]} + {1'b0,clip1y10to8(truncate((workVector15[ii+12]+16)>>5))} + 1) >> 1);
392
                     end
393
                  for(Integer ii=0; ii<16; ii=ii+1)
394
                     workVector15Next[ii] = workVector15[ii+4];
395
                  for(Integer ii=0; ii<4; ii=ii+1)
396
                     workVector15Next[ii+16] = readdata[ii];
397
                  Bit#(2) workHorNumMax = 1;
398
                  Bit#(4) workVerNumMax = (blockT==IP8x8||blockT==IP4x8 ? 7 : 3) + 5;
399
                  if(workVerNum > 4)
400
                     begin
401
                        Bit#(1) horAddr = truncate(workHorNum);
402
                        Bit#(3) verAddr = truncate(workVerNum-5);
403
                        horAddr = horAddr + ((blockT==IP4x8&&workSubMbPart==1)||(blockT==IP4x4&&workSubMbPart[0]==1) ? 1 : 0);
404
                        verAddr = verAddr + ((blockT==IP8x4&&workSubMbPart==1)||(blockT==IP4x4&&workSubMbPart[1]==1) ? 4 : 0);
405
                        resultFile.upd({verAddr,horAddr},tempResult8);
406
                        if(verAddr[1:0] == 3)
407
                           resultReadyNext[{verAddr[2],horAddr}] = 1;
408
                     end
409
                  if(workVerNum < workVerNumMax)
410
                     workVerNum <= workVerNum+1;
411
                  else
412
                     begin
413
                        workVerNum <= 0;
414
                        if(workHorNum < workHorNumMax)
415
                           workHorNum <= workHorNum+1;
416
                        else
417
                           begin
418
                              workHorNum <= 0;
419
                              workStage <= 0;
420
                              if(((blockT==IP4x8 || blockT==IP8x4) && workSubMbPart==0) || (blockT==IP4x4 && workSubMbPart<3))
421
                                 workSubMbPart <= workSubMbPart+1;
422
                              else
423
                                 begin
424
                                    workSubMbPart <= 0;
425
                                    workDone <= True;
426
                                 end
427
                              reqfifoWork.deq();
428
                           end
429
                     end
430
               end
431
            else//horizontal interpolation
432
               begin
433
                  offset = offset-2;
434
                  if(yfracl == 2)
435
                     begin
436
                        readdata = workFile.sub({workVerNum[2:0],workHorNum});
437
                        for(Integer ii=0; ii<8; ii=ii+1)
438
                           workVector15Next[ii] = workVector15[ii+4];
439
                        for(Integer ii=0; ii<4; ii=ii+1)
440
                           begin
441
                              Bit#(4) tempIndex = fromInteger(ii) + 8 - zeroExtend(offset);
442
                              workVector15Next[tempIndex] = readdata[ii];
443
                           end
444
                        for(Integer ii=0; ii<4; ii=ii+1)
445
                           begin
446
                              tempResult8[ii] = interpolate15to8(workVector15Next[ii],workVector15Next[ii+1],workVector15Next[ii+2],workVector15Next[ii+3],workVector15Next[ii+4],workVector15Next[ii+5]);
447
                              if(xfracl == 1)
448
                                 tempResult8[ii] = truncate(({1'b0,tempResult8[ii]} + {1'b0,clip1y10to8(truncate((workVector15Next[ii+2]+16)>>5))} + 1) >> 1);
449
                              else if(xfracl == 3)
450
                                 tempResult8[ii] = truncate(({1'b0,tempResult8[ii]} + {1'b0,clip1y10to8(truncate((workVector15Next[ii+3]+16)>>5))} + 1) >> 1);
451
                           end
452
                     end
453
                  else
454
                     begin
455
                        if(memRespQ.first() matches tagged IPLoadResp .tempreaddata8)
456
                           begin
457
                              memRespQ.deq();
458
                              Vector#(4,Bit#(8)) readdata8 = replicate(0);
459
                              readdata8[0] = tempreaddata8[7:0];
460
                              readdata8[1] = tempreaddata8[15:8];
461
                              readdata8[2] = tempreaddata8[23:16];
462
                              readdata8[3] = tempreaddata8[31:24];
463
                              for(Integer ii=0; ii<8; ii=ii+1)
464
                                 workVector8Next[ii] = workVector8[ii+4];
465
                              for(Integer ii=0; ii<4; ii=ii+1)
466
                                 begin
467
                                    Bit#(4) tempIndex = fromInteger(ii) + 8 - zeroExtend(offset);
468
                                    workVector8Next[tempIndex] = readdata8[ii];
469
                                 end
470
                              Vector#(4,Bit#(15)) tempResult15 = replicate(0);
471
                              for(Integer ii=0; ii<4; ii=ii+1)
472
                                 begin
473
                                    tempResult15[ii] = interpolate8to15(workVector8Next[ii],workVector8Next[ii+1],workVector8Next[ii+2],workVector8Next[ii+3],workVector8Next[ii+4],workVector8Next[ii+5]);
474
                                    tempResult8[ii] = clip1y10to8(truncate((tempResult15[ii]+16)>>5));
475
                                 end
476
                              Bit#(2) verOffset;
477
                              Vector#(4,Bit#(15)) verResult15 = replicate(0);
478
                              if(xfracl == 1)
479
                                 verOffset = reqdata.offset;
480
                              else
481
                                 verOffset = reqdata.offset+1;
482
                              readdata = workFile.sub({workVerNum[2:0],(workHorNum-2+(verOffset==0?0:1))});
483
                              for(Integer ii=0; ii<4; ii=ii+1)
484
                                 begin
485
                                    Bit#(2) offsetplusii = verOffset+fromInteger(ii);
486
                                    if(verOffset <= 3-fromInteger(ii) && verOffset!=0)
487
                                       verResult15[ii] = workVector15[offsetplusii];
488
                                    else
489
                                       verResult15[ii] = readdata[offsetplusii];
490
                                    workVector15Next[ii] = readdata[ii];
491
                                 end
492
                              for(Integer ii=0; ii<4; ii=ii+1)
493
                                 begin
494
                                    Bit#(9) tempVal = zeroExtend(clip1y10to8(truncate((verResult15[ii]+16)>>5)));
495
                                    tempResult8[ii] = truncate((tempVal+zeroExtend(tempResult8[ii])+1)>>1);
496
                                 end
497
                           end
498
                     end
499
                  if(workHorNum >= 2)
500
                     begin
501
                        Bit#(1) horAddr = truncate(workHorNum-2);
502
                        Bit#(3) verAddr = truncate(workVerNum);
503
                        horAddr = horAddr + ((blockT==IP4x8&&workSubMbPart==1)||(blockT==IP4x4&&workSubMbPart[0]==1) ? 1 : 0);
504
                        verAddr = verAddr + ((blockT==IP8x4&&workSubMbPart==1)||(blockT==IP4x4&&workSubMbPart[1]==1) ? 4 : 0);
505
                        resultFile.upd({verAddr,horAddr},tempResult8);
506
                        if(verAddr[1:0] == 3)
507
                           resultReadyNext[{verAddr[2],horAddr}] = 1;
508
                        //$display( "Trace interpolator: workLuma stage 1 result %h %h %h %h %h %h %h %h", workHorNum, workVerNum, {verAddr,horAddr}, tempResult8[3], tempResult8[2], tempResult8[1], tempResult8[0], pack(resultReadyNext));
509
                     end
510
                  Bit#(2) workHorNumMax = (blockT==IP8x8||blockT==IP8x4 ? 1 : 0) + 2;
511
                  Bit#(4) workVerNumMax = (blockT==IP8x8||blockT==IP4x8 ? 7 : 3);
512
                  if(workHorNum < workHorNumMax)
513
                     workHorNum <= workHorNum+1;
514
                  else
515
                     begin
516
                        workHorNum <= 0;
517
                        if(workVerNum < workVerNumMax)
518
                           workVerNum <= workVerNum+1;
519
                        else
520
                           begin
521
                              workVerNum <= 0;
522
                              workStage <= 0;
523
                              if(((blockT==IP4x8 || blockT==IP8x4) && workSubMbPart==0) || (blockT==IP4x4 && workSubMbPart<3))
524
                                 workSubMbPart <= workSubMbPart+1;
525
                              else
526
                                 begin
527
                                    workSubMbPart <= 0;
528
                                    workDone <= True;
529
                                 end
530
                              reqfifoWork.deq();
531
                           end
532
                     end
533
               end
534
         end
535
      workVector8 <= workVector8Next;
536
      workVector15 <= workVector15Next;
537
      resultReady <= resultReadyNext;
538
      //$display( "Trace interpolator: workLuma %h %h %h %h %h %h", xfracl, yfracl, workHorNum, workVerNum, offset, workStage);
539
   endrule
540
 
541
 
542
   rule workChroma ( reqfifoWork.first() matches tagged IPWChroma .reqdata &&& !workDone );
543
      Bit#(4) xfracc = zeroExtend(reqdata.xFracC);
544
      Bit#(4) yfracc = zeroExtend(reqdata.yFracC);
545
      let offset = reqdata.offset;
546
      let blockT = reqdata.bt;
547
      Vector#(20,Bit#(8)) workVector8Next = workVector8;
548
      Vector#(4,Bit#(1)) resultReadyNext = resultReady;
549
      if(memRespQ.first() matches tagged IPLoadResp .tempreaddata)
550
         begin
551
            memRespQ.deq();
552
            Vector#(4,Bit#(8)) readdata = replicate(0);
553
            readdata[0] = tempreaddata[7:0];
554
            readdata[1] = tempreaddata[15:8];
555
            readdata[2] = tempreaddata[23:16];
556
            readdata[3] = tempreaddata[31:24];
557
            Vector#(5,Bit#(8)) tempWork8 = replicate(0);
558
            Vector#(5,Bit#(8)) tempPrev8 = replicate(0);
559
            Vector#(4,Bit#(8)) tempResult8 = replicate(0);
560
            Bool resultReadyFlag = False;
561
            for(Integer ii=0; ii<4; ii=ii+1)
562
               begin
563
                  Bit#(2) offsetplusii = offset+fromInteger(ii);
564
                  if(offset <= 3-fromInteger(ii) && !((blockT==IP4x8||blockT==IP4x4)&&(offset[1]==0||(xfracc==0&&offset!=3))) && !(xfracc==0&&offset==0))
565
                     tempWork8[ii] = workVector8[offsetplusii];
566
                  else
567
                     tempWork8[ii] = readdata[offsetplusii];
568
                  workVector8Next[ii] = readdata[ii];
569
               end
570
            tempWork8[4] = readdata[offset];
571
            if((blockT==IP16x8 || blockT==IP16x16) && workHorNum==(xfracc==0&&offset==0 ? 1 : 2))
572
               begin
573
                  for(Integer ii=0; ii<5; ii=ii+1)
574
                     begin
575
                        tempPrev8[ii] = workVector8[ii+9];
576
                        workVector8Next[ii+9] = tempWork8[ii];
577
                     end
578
               end
579
            else
580
               begin
581
                  for(Integer ii=0; ii<5; ii=ii+1)
582
                     tempPrev8[ii] = workVector8[ii+4];
583
                  if(workHorNum==(xfracc==0&&offset==0 ? 0 : 1) || ((blockT==IP4x8||blockT==IP4x4)&&(offset[1]==0||(xfracc==0&&offset!=3))))
584
                     begin
585
                        for(Integer ii=0; ii<5; ii=ii+1)
586
                           workVector8Next[ii+4] = tempWork8[ii];
587
                     end
588
               end
589
            if(yfracc==0)
590
               begin
591
                  for(Integer ii=0; ii<5; ii=ii+1)
592
                     tempPrev8[ii] = tempWork8[ii];
593
               end
594
            for(Integer ii=0; ii<4; ii=ii+1)
595
               begin
596
                  Bit#(14) tempVal = zeroExtend((8-xfracc))*zeroExtend((8-yfracc))*zeroExtend(tempPrev8[ii]);
597
                  tempVal = tempVal + zeroExtend(xfracc)*zeroExtend((8-yfracc))*zeroExtend(tempPrev8[ii+1]);
598
                  tempVal = tempVal + zeroExtend((8-xfracc))*zeroExtend(yfracc)*zeroExtend(tempWork8[ii]);
599
                  tempVal = tempVal + zeroExtend(xfracc)*zeroExtend(yfracc)*zeroExtend(tempWork8[ii+1]);
600
                  tempResult8[ii] = truncate((tempVal+32)>>6);
601
               end
602
            if(workVerNum > 0 || yfracc==0)
603
               begin
604
                  if(blockT==IP4x8 || blockT==IP4x4)
605
                     begin
606
                        Bit#(5) tempIndex = 10 + zeroExtend(workVerNum<<1);
607
                        workVector8Next[tempIndex] = tempResult8[0];
608
                        workVector8Next[tempIndex+1] = tempResult8[1];
609
                        tempResult8[2] = tempResult8[0];
610
                        tempResult8[3] = tempResult8[1];
611
                        tempResult8[0] = workVector8[tempIndex];
612
                        tempResult8[1] = workVector8[tempIndex+1];
613
                        if((workHorNum>0 || offset[1]==0) && workSubMbPart[0]==1)
614
                           resultReadyFlag = True;
615
                     end
616
                  else
617
                     begin
618
                        if(workHorNum>0 || (xfracc==0 && offset==0))
619
                           resultReadyFlag = True;
620
                     end
621
               end
622
            if(resultReadyFlag)
623
               begin
624
                  Bit#(1) horAddr = ((blockT==IP4x8 || blockT==IP4x4) ? 0 : truncate(((xfracc==0 && offset==0) ? workHorNum : workHorNum-1)));
625
                  Bit#(3) verAddr = truncate((yfracc==0 ? workVerNum : workVerNum-1));
626
                  horAddr = horAddr + ((blockT==IP16x8||blockT==IP16x16) ? 0 : workMbPart[0]);
627
                  verAddr = verAddr + ((blockT==IP8x16||blockT==IP16x16) ? 0 : ((blockT==IP16x8) ? {workMbPart[0],2'b00} : {workMbPart[1],2'b00}));
628
                  verAddr = verAddr + ((blockT==IP8x4&&workSubMbPart==1)||(blockT==IP4x4&&workSubMbPart[1]==1) ? 2 : 0);
629
                  resultFile.upd({verAddr,horAddr},tempResult8);
630
                  if(verAddr[1:0] == 3)
631
                     resultReadyNext[{verAddr[2],horAddr}] = 1;
632
               end
633
            Bit#(2) workHorNumMax = (blockT==IP4x8||blockT==IP4x4 ? (offset[1]==0||(xfracc==0&&offset!=3) ? 0 : 1) : ((blockT==IP16x16||blockT==IP16x8 ? 1 : 0) + (xfracc==0&&offset==0 ? 0 : 1)));
634
            Bit#(4) workVerNumMax = (blockT==IP16x16||blockT==IP8x16 ? 7 : (blockT==IP16x8||blockT==IP8x8||blockT==IP4x8 ? 3 : 1)) + (yfracc==0 ? 0 : 1);
635
            if(workHorNum < workHorNumMax)
636
               workHorNum <= workHorNum+1;
637
            else
638
               begin
639
                  workHorNum <= 0;
640
                  if(workVerNum < workVerNumMax)
641
                     workVerNum <= workVerNum+1;
642
                  else
643
                     begin
644
                        workVerNum <= 0;
645
                        if(((blockT==IP4x8 || blockT==IP8x4) && workSubMbPart==0) || (blockT==IP4x4 && workSubMbPart<3))
646
                           workSubMbPart <= workSubMbPart+1;
647
                        else
648
                           begin
649
                              workSubMbPart <= 0;
650
                              if(((blockT==IP16x8 || blockT==IP8x16) && workMbPart==0) || (!(blockT==IP16x8 || blockT==IP8x16 || blockT==IP16x16) && workMbPart<3))
651
                                 workMbPart <= workMbPart+1;
652
                              else
653
                                 begin
654
                                    workMbPart <= 0;
655
                                    workDone <= True;
656
                                 end
657
                           end
658
                        reqfifoWork.deq();
659
                     end
660
               end
661
         end
662
      workVector8 <= workVector8Next;
663
      resultReady <= resultReadyNext;
664
      //$display( "Trace interpolator: workChroma %h %h %h %h %h", xfracc, yfracc, workHorNum, workVerNum, offset);
665
   endrule
666
 
667
 
668
   rule outputing( !outDone && resultReady[outBlockNum]==1 );
669
      outfifo.enq(resultFile.sub({outBlockNum[1],outPixelNum,outBlockNum[0]}));
670
      outPixelNum <= outPixelNum+1;
671
      if(outPixelNum == 3)
672
         begin
673
            outBlockNum <= outBlockNum+1;
674
            if(outBlockNum == 3)
675
               outDone <= True;
676
         end
677
      //$display( "Trace interpolator: outputing %h %h %h %h %h %h", outBlockNum, outPixelNum, tempVector[3], tempVector[2], tempVector[1], tempVector[0]);
678
   endrule
679
 
680
 
681
   rule switching( outDone && workDone );
682
      outDone <= False;
683
      workDone <= False;
684
      resultReady <= replicate(0);
685
      //$display( "Trace interpolator: switching %h %h", outBlockNum, outPixelNum);
686
   endrule
687
 
688
 
689
   method Action   setPicWidth( Bit#(PicWidthSz) newPicWidth );
690
      picWidth <= newPicWidth;
691
   endmethod
692
 
693
   method Action   setPicHeight( Bit#(PicHeightSz) newPicHeight );
694
      picHeight <= newPicHeight;
695
   endmethod
696
 
697
   method Action request( InterpolatorIT inputdata );
698
      reqfifoLoad.enq(inputdata);
699
      if(inputdata matches tagged IPLuma .indata)
700
         reqfifoWork.enq(IPWLuma {xFracL:indata.mvhor[1:0],yFracL:indata.mvver[1:0],offset:indata.mvhor[3:2],bt:indata.bt});
701
      else if(inputdata matches tagged IPChroma .indata)
702
         reqfifoWork.enq(IPWChroma {xFracC:indata.mvhor[2:0],yFracC:indata.mvver[2:0],offset:indata.mvhor[4:3]+{indata.hor[0],1'b0},bt:indata.bt});
703
   endmethod
704
 
705
   method Vector#(4,Bit#(8)) first();
706
      return outfifo.first();
707
   endmethod
708
 
709
   method Action deq();
710
      outfifo.deq();
711
   endmethod
712
 
713
   method Action endOfFrame();
714
      endOfFrameFlag <= True;
715
   endmethod
716
 
717
   interface Client mem_client;
718
      interface Get request  = fifoToGet(memReqQ);
719
      interface Put response = fifoToPut(memRespQ);
720
   endinterface
721
 
722
 
723
endmodule
724
 
725
 
726
endpackage

powered by: WebSVN 2.1.0

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