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

Subversion Repositories bluespec-h264

[/] [bluespec-h264/] [trunk/] [src/] [mkInverseTrans.bsv] - Rev 100

Compare with Previous | Blame | View Log


// The MIT License

// Copyright (c) 2006-2007 Massachusetts Institute of Technology

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//**********************************************************************
// Inverse Quantizer and Inverse Transformer implementation
//----------------------------------------------------------------------
//
//

package mkInverseTrans;

import H264Types::*;

import IInverseTrans::*;
import FIFO::*;
import Vector::*;

import Connectable::*;
import GetPut::*;
import ClientServer::*;


//-----------------------------------------------------------
// Local Datatypes
//-----------------------------------------------------------

typedef union tagged                
{
 void     Start;            //not working on anything in particular
 void     Intra16x16DC;
 void     Intra16x16;
 void     ChromaDC;
 void     Chroma;
 void     Regular4x4;
}
State deriving(Eq,Bits);

typedef union tagged                
{
 void     Passing;          //not working on anything in particular
 void     LoadingDC;
 void     Scaling;          //does not include scaling for DC (just loading in that case)
 void     TransformingDC;
 void     ScalingDC;
}
Process deriving(Eq,Bits);

typedef union tagged                
{
 void     Invalid;
 void     Zeros;
 Vector#(16,Bit#(16)) Values;
}
PipeType deriving(Eq,Bits);

      
//-----------------------------------------------------------
// Helper functions

function Bit#(6) qpi_to_qpc( Bit#(6) qpi );//mapping from qpi to qpc
   case ( qpi )
      30: return 29;
      31: return 30;
      32: return 31;
      33: return 32;
      34: return 32;
      35: return 33;
      36: return 34;
      37: return 34;
      38: return 35;
      39: return 35;
      40: return 36;
      41: return 36;
      42: return 37;
      43: return 37;
      44: return 37;
      45: return 38;
      46: return 38;
      47: return 38;
      48: return 39;
      49: return 39;
      50: return 39;
      51: return 39;
      default: return qpi;
   endcase
endfunction


function Bit#(4) reverseInverseZigZagScan( Bit#(4) idx );
   case ( idx )
      0: return 15;
      1: return 14;
      2: return 11;
      3: return 7;
      4: return 10;
      5: return 13;
      6: return 12;
      7: return 9;
      8: return 6;
      9: return 3;
      10: return 2;
      11: return 5;
      12: return 8;
      13: return 4;
      14: return 1;
      15: return 0;
   endcase
endfunction


function Tuple2#(Bit#(4),Bit#(3)) qpdivmod6( Bit#(6) qp );
   Bit#(6) tempqp = qp;
   Bit#(4) tempdiv = 0;
   for(Integer ii=5; ii>=2; ii=ii-1)
      begin
         if(tempqp >= (6'b000011 << (fromInteger(ii)-1)))
            begin
               tempqp = tempqp - (6'b000011 << (fromInteger(ii)-1));
               tempdiv = tempdiv | (4'b0001 << (fromInteger(ii)-2));
            end
      end
   return tuple2(tempdiv,truncate(tempqp));
endfunction


function Vector#(4,Bit#(16)) dcTransFunc( Bit#(16) in0, Bit#(16) in1, Bit#(16) in2, Bit#(16) in3 );
   Vector#(4,Bit#(16)) resultVector = replicate(0);
   resultVector[0] = in0 + in1 + in2 + in3;
   resultVector[1] = in0 + in1 - in2 - in3;
   resultVector[2] = in0 - in1 - in2 + in3;
   resultVector[3] = in0 - in1 + in2 - in3;
   return resultVector;
endfunction


function Vector#(4,Bit#(16)) transFunc( Bit#(16) in0, Bit#(16) in1, Bit#(16) in2, Bit#(16) in3 );
   Vector#(4,Bit#(16)) resultVector = replicate(0);
   Bit#(16) workValue0 = in0 + in2;
   Bit#(16) workValue1 = in0 - in2;
   Bit#(16) workValue2 = signedShiftRight(in1,1) - in3;
   Bit#(16) workValue3 = in1 + signedShiftRight(in3,1);
   resultVector[0] = workValue0 + workValue3;
   resultVector[1] = workValue1 + workValue2;
   resultVector[2] = workValue1 - workValue2;
   resultVector[3] = workValue0 - workValue3;
   return resultVector;
endfunction


//-----------------------------------------------------------
// Inverse Quantizer and Inverse Transformer Module
//-----------------------------------------------------------


(* synthesize *)
module mkInverseTrans( IInverseTrans );

   FIFO#(EntropyDecOT_InverseTrans) infifo  <- mkSizedFIFO(inverseTrans_infifo_size);
   FIFO#(InverseTransOT)            outfifo <- mkFIFO;
   Reg#(Bit#(4))       blockNum <- mkReg(0);
   Reg#(Bit#(4))       pixelNum <- mkReg(0);//also used as a regular counter during inverse transformation
   Reg#(State)         state    <- mkReg(Start);
   Reg#(Process)       process  <- mkReg(Passing);

   Reg#(Bit#(5))        chroma_qp_index_offset <- mkReg(0);
   Reg#(Bit#(6))        ppspic_init_qp <- mkReg(0);
   Reg#(Bit#(6))        slice_qp       <- mkReg(0);
   Reg#(Bit#(6))        qpy            <- mkReg(0);//Calculating it requires 8 bits, but value only 0 to 51
   Reg#(Bit#(6))        qpc            <- mkReg(0);
   Reg#(Bit#(3))        qpymod6        <- mkReg(0);
   Reg#(Bit#(3))        qpcmod6        <- mkReg(0);
   Reg#(Bit#(4))        qpydiv6        <- mkReg(0);
   Reg#(Bit#(4))        qpcdiv6        <- mkReg(0);

   Reg#(Vector#(16,Bit#(16))) storeVector <- mkRegU();
   Reg#(Vector#(16,Bit#(16))) workVector  <- mkRegU();
   Reg#(PipeType)             work2Vector <- mkReg(Invalid);
   Reg#(PipeType)             work3Vector <- mkReg(Invalid);
   Reg#(Bool)                 stage1Zeros <- mkReg(False);
   Reg#(Bool)                 stage1Done  <- mkReg(False);
   Reg#(Bool)                 stage2Done  <- mkReg(False);
   Reg#(Bool)                 stage3Done  <- mkReg(False);
   Reg#(Bit#(3))              stage2Step  <- mkReg(0);
   Reg#(Bit#(2))              stage3Step  <- mkReg(0);

   

   //-----------------------------------------------------------
   // Rules

   
   rule passing (process==Passing && work2Vector==Invalid && (stage3Done || work3Vector==Invalid) );
      //$display( "Trace Inverse Trans: passing infifo packed %h", pack(infifo.first()));
      case (infifo.first()) matches
         tagged NewUnit . xdata :
            begin
               infifo.deq();
               $display("ccl3newunit");
               $display("ccl3rbspbyte %h", xdata);
            end
         tagged SDMmbtype .xdata :
            begin
               infifo.deq();
               $display( "INFO InverseTrans: SDMmbtype %0d", xdata);
               if(mbPartPredMode(xdata,0) == Intra_16x16)
                  state <= Intra16x16DC;
               else
                  state <= Regular4x4;
            end
         tagged PPSpic_init_qp .xdata :
            begin
               infifo.deq();
               ppspic_init_qp <= truncate(xdata);
            end
         tagged SHslice_qp_delta .xdata :
            begin
               infifo.deq();
               slice_qp <= ppspic_init_qp+truncate(xdata);
               Bit#(6) qpynext = ppspic_init_qp+truncate(xdata);
               qpy <= qpynext;
               Bit#(7) qpitemp = zeroExtend(chroma_qp_index_offset+12) + zeroExtend(qpynext);
               Bit#(6) qpi;
               if(qpitemp < 12)
                  qpi = 0;
               else if(qpitemp > 63)
                  qpi = 51;
               else
                  qpi = truncate(qpitemp-12);
               qpc <= qpi_to_qpc(qpi);
               outfifo.enq(IBTmb_qp {qpy:qpynext,qpc:qpi_to_qpc(qpi)});
            end
         tagged SDMmb_qp_delta .xdata :
            begin
               infifo.deq();
               Bit#(8) qpytemp = zeroExtend(qpy) + zeroExtend(xdata+52);
               Bit#(6) qpynext;
               if(qpytemp >= 104)
                  qpynext = truncate(qpytemp - 104);
               else if(qpytemp >= 52)
                  qpynext = truncate(qpytemp - 52);
               else
                  qpynext = truncate(qpytemp);
               qpy <= qpynext;
               
               //$display( "TRACE InverseTrans: qpy %0d", qpynext );
               //$display( "TRACE InverseTrans: qpy %0d", qpynext );
               Tuple2#(Bit#(4),Bit#(3)) temptuple = qpdivmod6(qpynext);
               qpydiv6 <= tpl_1(temptuple);
               qpymod6 <= tpl_2(temptuple);
               //$display( "TRACE InverseTrans: qpydiv6 %0d", tpl_1(temptuple) );
               //$display( "TRACE InverseTrans: qpymod6 %0d", tpl_2(temptuple) );

               Bit#(7) qpitemp = zeroExtend(chroma_qp_index_offset+12) + zeroExtend(qpynext);
               Bit#(6) qpi;
               if(qpitemp < 12)
                  qpi = 0;
               else if(qpitemp > 63)
                  qpi = 51;
               else
                  qpi = truncate(qpitemp-12);
               qpc <= qpi_to_qpc(qpi);
               outfifo.enq(IBTmb_qp {qpy:qpynext,qpc:qpi_to_qpc(qpi)});
            end
         tagged PPSchroma_qp_index_offset .xdata :
            begin
               infifo.deq();
               chroma_qp_index_offset <= xdata;
            end
         tagged SDMRcoeffLevelPlusZeros .xdata :
            begin
               blockNum <= 0;
               pixelNum <= 0;
               if(state == Intra16x16DC)
                  begin
                     $display( "INFO InverseTrans: 16x16 MB" );
                     process <= LoadingDC;
                  end
               else
                  begin
                     $display( "INFO InverseTrans: Non-16x16 MB" );
                     process <= Scaling;
                  end
               workVector <= replicate(0);
               Tuple2#(Bit#(4),Bit#(3)) temptuple = qpdivmod6(qpc);
               qpcdiv6 <= tpl_1(temptuple);
               qpcmod6 <= tpl_2(temptuple);
            end
         tagged SDMRcoeffLevelZeros .xdata :
            begin
               blockNum <= 0;
               pixelNum <= 0;
               if(state == Intra16x16DC)
                  begin
                     $display( "INFO InverseTrans: 16x16 MB" );
                     process <= LoadingDC;
                  end
               else
                  begin
                     $display( "INFO InverseTrans: Non-16x16 MB" );
                     process <= Scaling;
                  end
               workVector <= replicate(0);
               Tuple2#(Bit#(4),Bit#(3)) temptuple = qpdivmod6(qpc);
               qpcdiv6 <= tpl_1(temptuple);
               qpcmod6 <= tpl_2(temptuple);
            end
         default: infifo.deq();
      endcase
   endrule


   rule loadingDC (process matches LoadingDC);
      Vector#(16,Bit#(16)) workVectorTemp = workVector;

      case (infifo.first()) matches
         tagged SDMRcoeffLevelZeros .xdata :
            begin
               infifo.deq();
               pixelNum <= pixelNum+truncate(xdata);
               if((state==ChromaDC && zeroExtend(pixelNum)+xdata==8) || zeroExtend(pixelNum)+xdata==16)
                  process <= TransformingDC;
               else if((state==ChromaDC && zeroExtend(pixelNum)+xdata>8) || zeroExtend(pixelNum)+xdata>16)
                  $display( "ERROR InverseTrans: loadingDC index overflow" );
            end
         tagged SDMRcoeffLevelPlusZeros .xdata :
            begin
               infifo.deq();
               Bit#(16) workValue = signExtend(xdata.level);
               if(state==ChromaDC)
                  begin
                     if(pixelNum<4)
                        workVector <= update(workVectorTemp, 3-pixelNum, workValue);
                     else
                        workVector <= update(workVectorTemp, 11-pixelNum, workValue);
                  end
               else
                  workVector <= update(workVectorTemp, reverseInverseZigZagScan(pixelNum), workValue);
               pixelNum <= pixelNum+1+truncate(xdata.zeros);
               if((state==ChromaDC && zeroExtend(pixelNum)+1+xdata.zeros==8) || zeroExtend(pixelNum)+1+xdata.zeros==16)
                  process <= TransformingDC;
               else if((state==ChromaDC && zeroExtend(pixelNum)+1+xdata.zeros>8) || zeroExtend(pixelNum)+1+xdata.zeros>16)
                  $display( "ERROR InverseTrans: loadingDC index overflow" );
            end
         default: process <= Passing;
      endcase
   endrule


   rule transformingDC (process matches TransformingDC);
      Vector#(16,Bit#(16)) workVectorTemp = workVector;
      Vector#(16,Bit#(16)) workVectorNew = workVector;
      Vector#(16,Bit#(16)) storeVectorTemp = storeVector;

      if(state == ChromaDC)
         begin
            case ( pixelNum )
               8:
               begin
                  workVectorNew[0] = workVectorTemp[0] + workVectorTemp[2];
                  workVectorNew[1] = workVectorTemp[1] + workVectorTemp[3];
                  workVectorNew[2] = workVectorTemp[0] - workVectorTemp[2];
                  workVectorNew[3] = workVectorTemp[1] - workVectorTemp[3];
                  pixelNum <= pixelNum+1;
               end
               9:
               begin
                  workVectorNew[0] = workVectorTemp[0] + workVectorTemp[1];
                  workVectorNew[1] = workVectorTemp[0] - workVectorTemp[1];
                  workVectorNew[2] = workVectorTemp[2] + workVectorTemp[3];
                  workVectorNew[3] = workVectorTemp[2] - workVectorTemp[3];
                  pixelNum <= pixelNum+1;
               end
               10:
               begin
                  workVectorNew[4] = workVectorTemp[4] + workVectorTemp[6];
                  workVectorNew[5] = workVectorTemp[5] + workVectorTemp[7];
                  workVectorNew[6] = workVectorTemp[4] - workVectorTemp[6];
                  workVectorNew[7] = workVectorTemp[5] - workVectorTemp[7];
                  pixelNum <= pixelNum+1;
               end
               11:
               begin
                  workVectorNew[4] = workVectorTemp[4] + workVectorTemp[5];
                  workVectorNew[5] = workVectorTemp[4] - workVectorTemp[5];
                  workVectorNew[6] = workVectorTemp[6] + workVectorTemp[7];
                  workVectorNew[7] = workVectorTemp[6] - workVectorTemp[7];
                  pixelNum <= 0;
                  process <= ScalingDC;
               end
               default:
                  $display( "ERROR InverseTrans: transformingDC ChromaDC unexpected pixelNum" );
            endcase
            workVector <= workVectorNew;
         end
      else if(state == Intra16x16DC)
         begin
            Vector#(4,Bit#(16)) resultVector = replicate(0);
            if(pixelNum < 4)
               begin
                  Bit#(4) tempIndex = zeroExtend(pixelNum[1:0]);
                  resultVector = dcTransFunc( workVectorTemp[tempIndex], workVectorTemp[tempIndex+4], workVectorTemp[tempIndex+8], workVectorTemp[tempIndex+12] );
                  for(Integer ii=0; ii<4; ii=ii+1)
                     workVectorNew[tempIndex+fromInteger(ii*4)] = resultVector[ii];
               end
            else if(pixelNum < 8)
               begin
                  Bit#(4) tempIndex = {pixelNum[1:0],2'b00};
                  resultVector = dcTransFunc( workVectorTemp[tempIndex], workVectorTemp[tempIndex+1], workVectorTemp[tempIndex+2], workVectorTemp[tempIndex+3] );
                  for(Integer ii=0; ii<4; ii=ii+1)
                     workVectorNew[tempIndex+fromInteger(ii)] = resultVector[ii];
               end
            else
               $display( "ERROR InverseTrans: transforming Intra16x16DC unexpected pixelNum" );
            workVector <= workVectorNew;
            if(pixelNum == 7)
               begin
                  pixelNum <= 0;
                  process <= ScalingDC;
               end
            else
               pixelNum <= pixelNum+1;
         end
      else
         $display( "ERROR InverseTrans: transformingDC unexpected state" );
   endrule

   
   rule scalingDC (process matches ScalingDC);
      Bit#(6)  qp;
      Bit#(4)  qpdiv6;
      Bit#(3)  qpmod6;
      Bit#(6)  workOne = 1;
      Bit#(16) workValue;
      Bit#(22) storeValueTemp;
      Bit#(16) storeValue;
      Vector#(16,Bit#(16)) workVectorTemp = workVector;
      Vector#(16,Bit#(16)) storeVectorTemp = storeVector;

      if(state==ChromaDC)
         begin
            qp = qpc;
            qpdiv6 = qpcdiv6;
            qpmod6 = qpcmod6;
         end
      else
         begin
            qp = qpy;
            qpdiv6 = qpydiv6;
            qpmod6 = qpymod6;
         end
      workValue = select(workVectorTemp, pixelNum);
      Bit#(5) levelScaleValue=0;
      case(qpmod6)
         0: levelScaleValue = 10;
         1: levelScaleValue = 11;
         2: levelScaleValue = 13;
         3: levelScaleValue = 14;
         4: levelScaleValue = 16;
         5: levelScaleValue = 18;
         default: $display( "ERROR InverseTrans: scalingDC levelScaleGen case default" );
      endcase
      storeValueTemp = zeroExtend(levelScaleValue)*signExtend(workValue);
      if(state==ChromaDC)
         storeValue = truncate( (storeValueTemp << zeroExtend(qpdiv6)) >> 1 );
      else
         begin
            if(qp >= 36)
               storeValue = truncate( storeValueTemp << zeroExtend(qpdiv6 - 2) );
            else
               storeValue = truncate( ((storeValueTemp << 4) + zeroExtend(workOne << zeroExtend(5-qpdiv6))) >> zeroExtend(6 - qpdiv6) );
         end
      storeVector <= update(storeVectorTemp, pixelNum, storeValue);
      if((state==ChromaDC && pixelNum==7) || pixelNum==15)
         begin
            blockNum <= 0;
            pixelNum <= 0;
            workVector <= replicate(0);
            if(state==ChromaDC)
               state <= Chroma;
            else
               state <= Intra16x16;
            process <= Scaling;
         end
      else if((state==ChromaDC && pixelNum>7) || pixelNum>15)
         $display( "ERROR InverseTrans: scalingDC index overflow" );
      else
         pixelNum <= pixelNum+1;
   endrule


   rule switching ( (stage1Done && work2Vector==Invalid) || (stage2Done && (stage3Done || work3Vector==Invalid)) );
      Bool switch2to3 = False;
      if(stage2Done && (stage3Done || work3Vector==Invalid))
         begin
            switch2to3 = True;
            work3Vector <= work2Vector;
            stage3Done <= False;
         end
      if(stage1Done && (switch2to3 || work2Vector==Invalid))
         begin
            Vector#(16,Bit#(16)) workVectorTemp = workVector;
            if(state==Intra16x16)
               workVectorTemp[0] = storeVector[{blockNum[3],blockNum[1],blockNum[2],blockNum[0]}];
            else if(state==Chroma)
               workVectorTemp[0] = storeVector[blockNum];
            if(stage1Zeros)
               work2Vector <= Zeros;
            else
               work2Vector <= (tagged Values workVectorTemp);
            stage1Zeros <= False;
            stage1Done <= False;
            workVector <= replicate(0);
            if(state==Chroma)
               begin
                  if(blockNum<7)
                     blockNum <= blockNum+1;
                  else if (blockNum==7)
                     begin
                        blockNum <= 0;
                        process <= Passing;
                     end
                  else
                     $display( "ERROR InverseTrans: switching chroma unexpected blockNum" );
               end
            else
               begin
                  blockNum <= blockNum+1;
                  if(blockNum==15)
                     begin
                        state <= ChromaDC;
                        process <= LoadingDC;
                     end
                  else
                     process <= Scaling;
               end
         end
      else //switch2to3==True
         work2Vector <= Invalid;
      stage2Done <= False;
   endrule


   rule scaling (process==Scaling && !stage1Done );
      Vector#(16,Bit#(16)) workVectorTemp = workVector;
      Vector#(16,Bit#(16)) storeVectorTemp = storeVector;

      case (infifo.first()) matches
         tagged SDMRcoeffLevelZeros .xdata :
            begin
               infifo.deq();
               if(zeroExtend(pixelNum)+xdata==16 || (zeroExtend(pixelNum)+xdata==15 && (state==Chroma || state==Intra16x16)))
                  begin
                     Bit#(16) prevValue0=0;
                     if(state==Intra16x16)
                        prevValue0 = select(storeVectorTemp, {blockNum[3],blockNum[1],blockNum[2],blockNum[0]});
                     else if(state==Chroma)
                        prevValue0 = select(storeVectorTemp, blockNum);
                     if(xdata==16 || (xdata==15 && (state==Chroma || state==Intra16x16) && prevValue0==0))
                        stage1Zeros <= True;
                     stage1Done <= True;
                     pixelNum <= 0;
                  end
               else if(zeroExtend(pixelNum)+xdata>16 || (zeroExtend(pixelNum)+xdata>15 && (state==Chroma || state==Intra16x16)))
                  $display( "ERROR InverseTrans: scaling index overflow" );
               else
                  pixelNum <= pixelNum+truncate(xdata);
               //$display( "TRACE InverseTrans: coeff zeros %0d", xdata );
            end
         tagged SDMRcoeffLevelPlusZeros .xdata :
            begin
               infifo.deq();
               Bit#(6)  qp;
               Bit#(4)  qpdiv6;
               Bit#(3)  qpmod6;
               if(state==Chroma)
                  begin
                     qp = qpc;
                     qpdiv6 = qpcdiv6;
                     qpmod6 = qpcmod6;
                  end
               else
                  begin
                     qp = qpy;
                     qpdiv6 = qpydiv6;
                     qpmod6 = qpymod6;
                  end
               Bit#(5) levelScaleValue=0;
               if(pixelNum==15 || pixelNum==12 || pixelNum==10 || pixelNum==4)
                  begin
                     case(qpmod6)
                        0: levelScaleValue = 10;
                        1: levelScaleValue = 11;
                        2: levelScaleValue = 13;
                        3: levelScaleValue = 14;
                        4: levelScaleValue = 16;
                        5: levelScaleValue = 18;
                        default: $display( "ERROR InverseTrans: levelScaleGen case default" );
                     endcase
                  end
               else if(pixelNum==11 || pixelNum==5 || pixelNum==3 || pixelNum==0)
                  begin
                     case(qpmod6)
                        0: levelScaleValue = 16;
                        1: levelScaleValue = 18;
                        2: levelScaleValue = 20;
                        3: levelScaleValue = 23;
                        4: levelScaleValue = 25;
                        5: levelScaleValue = 29;
                        default: $display( "ERROR InverseTrans: levelScaleGen case default" );
                     endcase
                  end
               else
                  begin
                     case(qpmod6)
                        0: levelScaleValue = 13;
                        1: levelScaleValue = 14;
                        2: levelScaleValue = 16;
                        3: levelScaleValue = 18;
                        4: levelScaleValue = 20;
                        5: levelScaleValue = 23;
                        default: $display( "ERROR InverseTrans: levelScaleGen case default" );
                     endcase
                  end
               Bit#(16) workValueTemp = zeroExtend(levelScaleValue)*signExtend(xdata.level);
               Bit#(16) workValue;
               workValue = workValueTemp << zeroExtend(qpdiv6);
               workVector <= update(workVectorTemp, reverseInverseZigZagScan(pixelNum), workValue);
               if(zeroExtend(pixelNum)+1+xdata.zeros==16 || (zeroExtend(pixelNum)+1+xdata.zeros==15 && (state==Chroma || state==Intra16x16)))
                  begin
                     stage1Done <= True;
                     pixelNum <= 0;
                  end
               else if(zeroExtend(pixelNum)+1+xdata.zeros>16 || (zeroExtend(pixelNum)+1+xdata.zeros>15 && (state==Chroma || state==Intra16x16)))
                  $display( "ERROR InverseTrans: scaling index overflow" );
               else
                  pixelNum <= pixelNum+1+truncate(xdata.zeros);
            end
         default: process <= Passing;
      endcase
   endrule


   rule transforming ( work2Vector!=Invalid && !stage2Done );
      if(work2Vector matches tagged Values .xdata)
         begin
            Vector#(16,Bit#(16)) work2VectorNew = xdata;
            if(stage2Step < 4)
               begin
                  Bit#(4) tempIndex = {stage2Step[1:0],2'b00};
                  Vector#(4,Bit#(16)) resultVector = transFunc( xdata[tempIndex], xdata[tempIndex+1], xdata[tempIndex+2], xdata[tempIndex+3] );
                  for(Integer ii=0; ii<4; ii=ii+1)
                     work2VectorNew[tempIndex+fromInteger(ii)] = resultVector[ii];
               end
            else
               begin
                  Bit#(4) tempIndex = zeroExtend(stage2Step[1:0]);
                  Vector#(4,Bit#(16)) resultVector = transFunc( xdata[tempIndex], xdata[tempIndex+4], xdata[tempIndex+8], xdata[tempIndex+12] );
                  for(Integer ii=0; ii<4; ii=ii+1)
                     work2VectorNew[tempIndex+fromInteger(ii*4)] = resultVector[ii];
               end
            work2Vector <= (tagged Values work2VectorNew);
            if(stage2Step == 7)
               stage2Done <= True;
            stage2Step <= stage2Step+1;
         end
      else //All Zeros
         stage2Done <= True;
   endrule


   rule outputing ( work3Vector!=Invalid && !stage3Done );
      if(work3Vector matches tagged Values .xdata)
         begin
            Vector#(4,Bit#(10)) outputVector = replicate(0);
            for(Integer ii=0; ii<4; ii=ii+1)
               outputVector[ii] = truncate((xdata[{stage3Step,2'b00}+fromInteger(ii)]+32) >> 6);
            outfifo.enq(tagged ITBresidual outputVector);
            Int#(10) tempint = unpack(outputVector[0]);
            $display("ccl3IBTresidual %0d", tempint);
            tempint = unpack(outputVector[1]);
            $display("ccl3IBTresidual %0d", tempint);
            tempint = unpack(outputVector[2]);
            $display("ccl3IBTresidual %0d", tempint);
            tempint = unpack(outputVector[3]);
            $display("ccl3IBTresidual %0d", tempint);
            if(stage3Step == 3)
               stage3Done <= True;
            stage3Step <= stage3Step+1;
         end
      else
         begin
            outfifo.enq(tagged ITBcoeffLevelZeros);
            stage3Done <= True;
         end
   endrule



   interface Put ioin  = fifoToPut(infifo);
   interface Get ioout = fifoToGet(outfifo);

      
endmodule

endpackage

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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