// 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. //********************************************************************** // Prediction //---------------------------------------------------------------------- // // package mkPrediction; import H264Types::*; import IPrediction::*; import IInterpolator::*; import mkInterpolator::*; import FIFO::*; import FIFOF::*; import Vector::*; import Connectable::*; import GetPut::*; import ClientServer::*; //----------------------------------------------------------- // Local Datatypes //----------------------------------------------------------- typedef union tagged { void Intra; //Intra non-4x4 void Intra4x4; void Inter; } OutState deriving(Eq,Bits); typedef union tagged { void Start; //not working on anything in particular void Intra16x16; void Intra4x4; void IntraPCM; } IntraState deriving(Eq,Bits); typedef union tagged { void Start; //not working on anything in particular void InterP16x16; void InterP16x8; void InterP8x16; void InterP8x8; void InterP8x8ref0; void InterPskip; } InterState deriving(Eq,Bits); typedef union tagged { Bit#(1) NotInter;//0 for not available, 1 for intra-coded struct {Bit#(4) refIdx; Bit#(14) mvhor; Bit#(12) mvver; Bit#(1) nonZeroTransCoeff;} BlockMv; } InterBlockMv deriving(Eq,Bits); typedef union tagged { void SkipMB; void NonSkipMB; void Intra4x4; void Intra4x4PlusChroma; } NextOutput deriving(Eq,Bits); //----------------------------------------------------------- // Helper functions function Bit#(8) intra4x4SelectTop( Bit#(72) valVector, Bit#(4) idx ); case(idx) 0: return valVector[15:8]; 1: return valVector[23:16]; 2: return valVector[31:24]; 3: return valVector[39:32]; 4: return valVector[47:40]; 5: return valVector[55:48]; 6: return valVector[63:56]; 7: return valVector[71:64]; default: return valVector[7:0]; endcase endfunction function Bit#(8) intra4x4SelectLeft( Bit#(40) valVector, Bit#(3) idx ); case(idx) 0: return valVector[15:8]; 1: return valVector[23:16]; 2: return valVector[31:24]; 3: return valVector[39:32]; default: return valVector[7:0]; endcase endfunction function Bit#(8) select32to8( Bit#(32) valVector, Bit#(2) idx ); case(idx) 0: return valVector[7:0]; 1: return valVector[15:8]; 2: return valVector[23:16]; 3: return valVector[31:24]; endcase endfunction function Bit#(8) select16to8( Bit#(16) valVector, Bit#(1) idx ); case(idx) 0: return valVector[7:0]; 1: return valVector[15:8]; endcase endfunction function Bool absDiffGEFour14( Bit#(14) val1, Bit#(14) val2 ); Int#(15) int1 = unpack(signExtend(val1)); Int#(15) int2 = unpack(signExtend(val2)); if(int1>=int2) return (int1 >= (int2+4)); else return (int2 >= (int1+4)); endfunction function Bool absDiffGEFour12( Bit#(12) val1, Bit#(12) val2 ); Int#(13) int1 = unpack(signExtend(val1)); Int#(13) int2 = unpack(signExtend(val2)); if(int1>=int2) return (int1 >= (int2+4)); else return (int2 >= (int1+4)); endfunction //----------------------------------------------------------- // Prediction Module //----------------------------------------------------------- (* synthesize *) module mkPrediction( IPrediction ); //Common state FIFO#(EntropyDecOT) infifo <- mkSizedFIFO(prediction_infifo_size); FIFO#(InverseTransOT) infifo_ITB <- mkSizedFIFO(prediction_infifo_ITB_size); FIFO#(EntropyDecOT) outfifo <- mkFIFO; Reg#(Bool) passFlag <- mkReg(True); Reg#(Bit#(4)) blockNum <- mkReg(0); Reg#(Bit#(4)) pixelNum <- mkReg(0); Reg#(Bit#(PicWidthSz)) picWidth <- mkReg(maxPicWidthInMB); Reg#(Bit#(PicHeightSz)) picHeight <- mkReg(0); Reg#(Bit#(PicAreaSz)) firstMb <- mkReg(0); Reg#(Bit#(PicAreaSz)) currMb <- mkReg(0); Reg#(Bit#(PicAreaSz)) currMbHor <- mkReg(0);//horizontal position of currMb Reg#(Bit#(PicHeightSz)) currMbVer <- mkReg(0);//vertical position of currMb FIFOF#(OutState) outstatefifo <- mkFIFOF; FIFOF#(NextOutput) nextoutputfifo <- mkFIFOF; Reg#(Bit#(4)) outBlockNum <- mkReg(0); Reg#(Bit#(4)) outPixelNum <- mkReg(0); FIFO#(Vector#(4,Bit#(8))) predictedfifo <- mkSizedFIFO(prediction_predictedfifo_size); Reg#(Bit#(1)) outChromaFlag <- mkReg(0); Reg#(Bool) outFirstQPFlag <- mkReg(False); DoNotFire donotfire <- mkDoNotFire(); //Reg#(Vector#(16,Bit#(8))) workVector <- mkRegU(); //Inter state Interpolator interpolator <- mkInterpolator(); Reg#(InterState) interstate <- mkReg(Start); Reg#(Bit#(PicAreaSz)) interPskipCount <- mkReg(0); Reg#(Vector#(5,InterBlockMv)) interTopVal <- mkRegU(); Reg#(Vector#(4,InterBlockMv)) interLeftVal <- mkRegU(); Reg#(Vector#(4,InterBlockMv)) interTopLeftVal <- mkRegU(); FIFO#(MemReq#(TAdd#(PicWidthSz,2),32)) interMemReqQ <- mkFIFO; Reg#(MemReq#(TAdd#(PicWidthSz,2),32)) interMemReqQdelay <- mkRegU(); FIFO#(MemResp#(32)) interMemRespQ <- mkFIFO; Reg#(Bit#(3)) interReqCount <- mkReg(0); Reg#(Bit#(3)) interRespCount <- mkReg(0); Reg#(Bit#(2)) interStepCount <- mkReg(0); Reg#(Bit#(2)) interMbPartNum <- mkReg(0); Reg#(Bit#(2)) interSubMbPartNum <- mkReg(0); Reg#(Bit#(2)) interPassingCount <- mkReg(0); Reg#(Vector#(4,Bit#(4))) interRefIdxVector <- mkRegU(); Reg#(Vector#(4,Bit#(2))) interSubMbTypeVector <- mkRegU(); RFile1#(Bit#(4),Tuple2#(Bit#(14),Bit#(12))) interMvFile <- mkRFile1Full(); Reg#(Bit#(15)) interMvDiffTemp <- mkReg(0); FIFO#(Tuple2#(Bit#(15),Bit#(13))) interMvDiff <- mkFIFO; Reg#(Bit#(5)) interNewestMv <- mkReg(0); // Registers for pipelining the interStage rule Reg#(Bit#(3)) partWidthR <- mkRegU(); Reg#(Bit#(3)) partHeightR <- mkRegU(); Reg#(Bit#(3)) numPartR <- mkRegU(); Reg#(Bit#(3)) numSubPartR <- mkRegU(); Reg#(Bit#(2)) subMbTypeR <- mkRegU(); Reg#(Bool) calcmvR <- mkRegU(); Reg#(Bool) leftmvR <- mkRegU(); Reg#(Bit#(4)) refIndexR <- mkRegU(); Reg#(Vector#(3,InterBlockMv)) blockABCR <- mkRegU(); Reg#(Bit#(14)) mvhorfinalR <- mkRegU(); Reg#(Bit#(12)) mvverfinalR <- mkRegU(); Reg#(Bit#(5)) interNewestMvNextR <- mkRegU(); Reg#(Bit#(2)) interIPStepCount <- mkReg(0); Reg#(Bit#(2)) interIPMbPartNum <- mkReg(0); Reg#(Bit#(2)) interIPSubMbPartNum <- mkReg(0); Reg#(Bit#(PicWidthSz)) interCurrMbDiff <- mkReg(0); Reg#(Vector#(4,Bool)) interTopNonZeroTransCoeff <- mkRegU(); Reg#(Vector#(4,Bool)) interLeftNonZeroTransCoeff <- mkRegU(); FIFO#(Tuple2#(Bit#(2),Bit#(2))) interBSfifo <- mkSizedFIFO(32); Reg#(Bool) interBSoutput <- mkReg(True); FIFO#(InterBlockMv) interOutBlockMvfifo <- mkSizedFIFO(8); //Intra state Reg#(IntraState) intrastate <- mkReg(Start); Reg#(Bit#(1)) intraChromaFlag <- mkReg(0); FIFO#(MemReq#(TAdd#(PicWidthSz,2),68)) intraMemReqQ <- mkFIFO; Reg#(MemReq#(TAdd#(PicWidthSz,2),68)) intraMemReqQdelay <- mkRegU; FIFO#(MemResp#(68)) intraMemRespQ <- mkFIFO; Reg#(Vector#(4,Bit#(4))) intra4x4typeLeft <- mkRegU();//15=unavailable, 14=inter-MB, 13=intra-non-4x4 Reg#(Vector#(4,Bit#(4))) intra4x4typeTop <- mkRegU();//15=unavailable, 14=inter-MB, 13=intra-non-4x4 Reg#(Bit#(1)) ppsconstrained_intra_pred_flag <- mkReg(0); Reg#(Vector#(4,Bit#(40))) intraLeftVal <- mkRegU(); Reg#(Vector#(9,Bit#(8))) intraLeftValChroma0 <- mkRegU(); Reg#(Vector#(9,Bit#(8))) intraLeftValChroma1 <- mkRegU(); Reg#(Vector#(5,Bit#(32))) intraTopVal <- mkRegU(); Reg#(Vector#(4,Bit#(16))) intraTopValChroma0 <- mkRegU(); Reg#(Vector#(4,Bit#(16))) intraTopValChroma1 <- mkRegU(); Reg#(Bit#(32)) intraLeftValNext <- mkReg(0); Reg#(Bit#(2)) intra16x16_pred_mode <- mkReg(0); FIFO#(Bit#(4)) rem_intra4x4_pred_mode <- mkSizedFIFO(16); FIFO#(Bit#(2)) intra_chroma_pred_mode <- mkFIFO; Reg#(Bit#(4)) cur_intra4x4_pred_mode <- mkReg(0); Reg#(Bit#(1)) intraChromaTopAvailable <- mkReg(0); Reg#(Bit#(1)) intraChromaLeftAvailable <- mkReg(0); Reg#(Bit#(3)) intraReqCount <- mkReg(0); Reg#(Bit#(3)) intraRespCount <- mkReg(0); Reg#(Bit#(4)) intraStepCount <- mkReg(0); Reg#(Bit#(13)) intraSumA <- mkReg(0); Reg#(Bit#(15)) intraSumB <- mkReg(0); Reg#(Bit#(15)) intraSumC <- mkReg(0); Reg#(Vector#(4,Bit#(8))) intraPredVector <- mkRegU(); //----------------------------------------------------------- // Rules ////////////////////////////////////////////////////////////////////////////// // rule stateMonitor ( True ); // if(predictedfifo.notEmpty()) // $display( "TRACE Prediction: stateMonitor predictedfifo.first() %0d", predictedfifo.first());//////////////////// // if(infifo.first() matches tagged ITBresidual .xdata) // $display( "TRACE Prediction: stateMonitor infifo.first() %0d", xdata);//////////////////// // if(infifo.first() matches tagged ITBresidual .xdata) // $display( "TRACE Prediction: stateMonitor outBlockNum outPixelNum outChromaFlag %0d %0d", outBlockNum, outPixelNum, outChromaFlag);//////////////////// // endrule ////////////////////////////////////////////////////////////////////////////// rule checkFIFO ( True ); $display( "Trace Prediction: checkFIFO %h", infifo.first() ); endrule rule checkFIFO_ITB ( True ); $display( "Trace Prediction: checkFIFO_ITB %h", infifo_ITB.first() ); endrule rule checkFIFO_predicted ( True ); $display( "Trace Prediction: checkFIFO_predicted %h", predictedfifo.first() ); endrule rule passing ( passFlag && !outstatefifo.notEmpty() && currMbHor 255) outputVector[ii] = 255; else outputVector[ii] = tempOutputValue[7:0]; end outfifo.enq(tagged PBoutput outputVector); infifo_ITB.deq(); predictedfifo.deq(); outputFlag = 1; $display( "Trace Prediction: outputing ITBresidual out %h %h %h %h %h %h", outChromaFlag, outBlockNum, outPixelNum, predictedfifo.first(), xdata, outputVector); end end tagged ITBcoeffLevelZeros : begin if(interBSoutput && outChromaFlag==0 && outPixelNum==0) begin interBSoutput <= False; if(outstatefifo.first() != Inter) outfifo.enq(tagged PBbS {bShor:(blockHor==0 ? 4 : 3),bSver:(blockVer==0 ? 4 : 3)}); else begin interBSfifo.deq(); Bit#(2) tempHorBS = tpl_1(interBSfifo.first()); Bit#(2) tempVerBS = tpl_2(interBSfifo.first()); Bit#(3) horBS = (tempHorBS==3 ? 4 : (interLeftNonZeroTransCoeff[blockVer] ? 2 : zeroExtend(tempHorBS))); Bit#(3) verBS = (tempVerBS==3 ? 4 : (interTopNonZeroTransCoeff[blockHor]&&blockVer!=0 ? 2 : zeroExtend(tempVerBS))); outfifo.enq(tagged PBbS {bShor:horBS,bSver:verBS}); end interLeftNonZeroTransCoeff <= update(interLeftNonZeroTransCoeff, blockVer, False); interTopNonZeroTransCoeff <= update(interTopNonZeroTransCoeff, blockHor, False); $display( "Trace Prediction: outputing ITBcoeffLevelZeros bS %h %h %h %h %h", outChromaFlag, outBlockNum, outPixelNum, currMbHor, currMbVer); end else begin interBSoutput <= True; if(outPixelNum == 12) infifo_ITB.deq(); outputVector = predictedfifo.first(); outfifo.enq(tagged PBoutput outputVector); outputFlag = 1; predictedfifo.deq(); $display( "Trace Prediction: outputing ITBcoeffLevelZeros out %h %h %h %h %h", outChromaFlag, outBlockNum, outPixelNum, predictedfifo.first(), outputVector); end end default: $display( "ERROR Prediction: outputing unknown infifo_ITB input" ); endcase end if(outputFlag == 1) begin $display("ccl4PBoutput %0d", outputVector[0]); $display("ccl4PBoutput %0d", outputVector[1]); $display("ccl4PBoutput %0d", outputVector[2]); $display("ccl4PBoutput %0d", outputVector[3]); if(outBlockNum==0 && pixelVer==0 && outChromaFlag==0 && currMb!=firstMb && picWidth>1) begin intraMemReqQ.enq(intraMemReqQdelay); interMemReqQ.enq(interMemReqQdelay); //$display( "TRACE Prediction: passing storing addr data");////////////////// end if(blockHor==3 || (blockHor[0]==1 && outChromaFlag==1) || (outstatefifo.first()==Intra4x4 && outChromaFlag==0)) begin if(outChromaFlag==0) begin Bit#(32) intraLeftValNextTemp = intraLeftValNext; if(totalVer==0 || (outstatefifo.first()==Intra4x4 && pixelVer==0)) begin Bit#(32) tempValSet = select(intraTopVal,blockHor); intraLeftValNextTemp = zeroExtend(tempValSet[31:24]); end case(pixelVer) 0:intraLeftValNext <= {intraLeftValNextTemp[31:16],outputVector[3],intraLeftValNextTemp[7:0]}; 1:intraLeftValNext <= {intraLeftValNextTemp[31:24],outputVector[3],intraLeftValNextTemp[15:0]}; 2:intraLeftValNext <= {outputVector[3],intraLeftValNextTemp[23:0]}; 3: begin intraLeftVal <= update(intraLeftVal,blockVer,{outputVector[3],intraLeftValNextTemp}); intraLeftValNext <= zeroExtend(outputVector[3]); if(outstatefifo.first()==Intra4x4) intra4x4typeLeft <= update(intra4x4typeLeft,blockVer,cur_intra4x4_pred_mode); else if(outstatefifo.first()==Intra) intra4x4typeLeft <= update(intra4x4typeLeft,blockVer,13); else intra4x4typeLeft <= update(intra4x4typeLeft,blockVer,14); end endcase end else begin if(outBlockNum[2]==0) intraLeftValChroma0 <= update(intraLeftValChroma0,totalVer+1,outputVector[3]); else intraLeftValChroma1 <= update(intraLeftValChroma1,totalVer+1,outputVector[3]); end end if(pixelVer==3 && (blockVer==3 || (blockVer[0]==1 && outChromaFlag==1) || (outstatefifo.first()==Intra4x4 && outChromaFlag==0))) begin if(outChromaFlag==0) begin intraTopVal <= update(intraTopVal,blockHor,{outputVector[3],outputVector[2],outputVector[1],outputVector[0]}); if(outstatefifo.first()==Intra4x4) intra4x4typeTop <= update(intra4x4typeTop,blockHor,cur_intra4x4_pred_mode); else if(outstatefifo.first()==Intra) intra4x4typeTop <= update(intra4x4typeTop,blockHor,13); else intra4x4typeTop <= update(intra4x4typeTop,blockHor,14); end else begin if(outBlockNum[2]==0) begin Vector#(4,Bit#(16)) intraTopValChroma0Next = intraTopValChroma0; intraTopValChroma0Next[{blockHor[0],1'b0}] = {outputVector[1],outputVector[0]}; intraTopValChroma0Next[{blockHor[0],1'b1}] = {outputVector[3],outputVector[2]}; intraTopValChroma0 <= intraTopValChroma0Next; end else begin Vector#(4,Bit#(16)) intraTopValChroma1Next = intraTopValChroma1; intraTopValChroma1Next[{blockHor[0],1'b0}] = {outputVector[1],outputVector[0]}; intraTopValChroma1Next[{blockHor[0],1'b1}] = {outputVector[3],outputVector[2]}; intraTopValChroma1 <= intraTopValChroma1Next; end end end if(outChromaFlag==1 && outBlockNum==7) begin Bit#(PicWidthSz) tempStoreAddr = truncate(currMbHor); InterBlockMv outBlockMv = interOutBlockMvfifo.first(); if(outBlockMv matches tagged BlockMv .bdata) begin outBlockMv = (tagged BlockMv {refIdx:bdata.refIdx,mvhor:bdata.mvhor,mvver:bdata.mvver,nonZeroTransCoeff:(interTopNonZeroTransCoeff[pixelVer]?1:0)}); interOutBlockMvfifo.deq(); end else if(pixelVer==3) interOutBlockMvfifo.deq(); if(pixelVer==3 && picWidth>1) interMemReqQdelay <= tagged StoreReq {addr:{tempStoreAddr,pixelVer},data:pack(outBlockMv)}; else interMemReqQ.enq(tagged StoreReq {addr:{tempStoreAddr,pixelVer},data:pack(outBlockMv)}); if(pixelVer>0) begin Bit#(4) intra4x4typeTopStore = ((outstatefifo.first()==Inter) ? 14 : ((outstatefifo.first()!=Intra4x4) ? 13: intra4x4typeTop[(pixelVer-1)])); Bit#(32) intraTopValStore = intraTopVal[(pixelVer-1)]; Bit#(16) intraTopValChroma0Store = intraTopValChroma0[(pixelVer-1)]; Bit#(16) intraTopValChroma1Store = (pixelVer<3 ? intraTopValChroma1[(pixelVer-1)] : {outputVector[1],outputVector[0]}); Bit#(68) intraStore = {intra4x4typeTopStore,intraTopValChroma1Store,intraTopValChroma0Store,intraTopValStore}; intraMemReqQ.enq(tagged StoreReq {addr:{tempStoreAddr,(pixelVer-1)},data:intraStore}); if(pixelVer==3) begin intra4x4typeTopStore = ((outstatefifo.first()==Inter) ? 14 : ((outstatefifo.first()!=Intra4x4) ? 13: intra4x4typeTop[3])); intraTopValStore = intraTopVal[3]; intraTopValChroma0Store = intraTopValChroma0[3]; intraTopValChroma1Store = {outputVector[3],outputVector[2]}; intraStore = {intra4x4typeTopStore,intraTopValChroma1Store,intraTopValChroma0Store,intraTopValStore}; intraMemReqQdelay <= tagged StoreReq {addr:{tempStoreAddr,2'b11},data:intraStore}; end end end outPixelNum <= outPixelNum+4; if(outPixelNum == 12) begin if(outChromaFlag==0) begin outBlockNum <= outBlockNum+1; if(outBlockNum == 15) outChromaFlag <= 1; if(nextoutputfifo.first() == Intra4x4) nextoutputfifo.deq(); end else begin if(outBlockNum == 7) begin outBlockNum <= 0; outChromaFlag <= 0; currMb <= currMb+1; currMbHor <= currMbHor+1; interCurrMbDiff <= interCurrMbDiff-1; outstatefifo.deq; intrastate <= Start; if(truncate(currMbHor)==picWidth-1 && currMbVer==picHeight-1) interpolator.endOfFrame(); nextoutputfifo.deq(); end else outBlockNum <= outBlockNum+1; end end end endrule rule currMbHorUpdate( !(currMbHor> 3) >= temp) begin currMbHor <= currMbHor - (temp << 3); currMbVer <= currMbVer + 8; end else begin currMbHor <= currMbHor - temp; currMbVer <= currMbVer + 1; end //$display( "Trace Prediction: currMbHorUpdate %h %h", currMbHor, currMbVer); endrule // inter prediction rules rule interSendReq ( interReqCount>0 && currMbHor= zeroExtend(picWidth) ) currMbHorTemp = currMbHorTemp-zeroExtend(picWidth); Bit#(PicWidthSz) temp2 = truncate(currMbHorTemp); Bit#(TAdd#(PicWidthSz,2)) temp = 0; Bool noMoreReq = False; if( currMbTemp < zeroExtend(picWidth) ) noMoreReq = True; else begin if(interReqCount<5) begin Bit#(2) temp3 = truncate(interReqCount-1); temp = {temp2,temp3}; end else if(interReqCount==5) begin if((currMbHorTemp+1)0 && currMbTemp-firstMb>zeroExtend(picWidth)) temp = {(temp2-1),2'b11}; else noMoreReq = True; end else if(interReqCount==6) begin if((currMbHorTemp+1)0 && currMbTemp-firstMb>zeroExtend(picWidth)) temp = {(temp2-1),2'b11}; else noMoreReq = True; end else noMoreReq = True; end if(!noMoreReq) begin interMemReqQ.enq(tagged LoadReq temp); interReqCount <= interReqCount+1; //$display( "TRACE Prediction: interSendReq addr %0d",temp);/////////////////////// end else interReqCount <= 0; $display( "Trace Prediction: interSendReq %h %h %h", interstate, interReqCount, temp); endrule rule interReceiveNoResp ( interRespCount>0 && currMbHor= zeroExtend(picWidth) ) currMbHorTemp = currMbHorTemp-zeroExtend(picWidth); interRespCount <= 0; interStepCount <= 1; interIPStepCount <= 1; if(currMbHorTemp == 0) begin interLeftVal <= replicate(tagged NotInter 0); interTopLeftVal <= replicate(tagged NotInter 0); end $display( "Trace Prediction: interReceiveNoResp %h %h", interstate, interRespCount); endrule rule interReceiveResp ( interRespCount>0 && interRespCount<7 && currMbHor= zeroExtend(picWidth) ) currMbHorTemp = currMbHorTemp-zeroExtend(picWidth); Bool noMoreResp = False; Bit#(2) temp2bit = 0; InterBlockMv unpackedData = unpack(data); Vector#(5,InterBlockMv) interTopValNext = interTopVal; Vector#(4,InterBlockMv) interTopLeftValNext = interTopLeftVal; if(interRespCount<5) begin temp2bit = truncate(interRespCount-1); interTopValNext[temp2bit] = unpackedData; if((interRespCount==4 || (interRespCount==1 && (interstate==InterPskip || interstate==InterP16x16 || interstate==InterP16x8))) && (!((currMbHorTemp+1)0 && currMbTemp-firstMb>zeroExtend(picWidth)))) noMoreResp = True; end else if(interRespCount==5) begin if((currMbHorTemp+1)0 && currMbTemp-firstMb>zeroExtend(picWidth))) noMoreResp = True; end else begin interTopLeftValNext[0] = unpackedData; noMoreResp = True; end end else begin interTopLeftValNext[0] = unpackedData; noMoreResp = True; end interMemRespQ.deq(); //$display( "TRACE Prediction: interReceiveResp data %h",data);/////////////////////// if(!noMoreResp) interRespCount <= interRespCount+1; else begin interRespCount <= 0; interStepCount <= 1; interIPStepCount <= 1; if(currMbHorTemp == 0) begin interLeftVal <= replicate(tagged NotInter 0); interTopLeftValNext = replicate(tagged NotInter 0); end end interTopVal <= interTopValNext; interTopLeftVal <= interTopLeftValNext; $display( "Trace Prediction: interReceiveResp %h %h %h", interstate, interRespCount, data); endrule rule interProcessStep ( interStepCount>0 && currMbHor0); end else if(interstate==InterP16x8) begin partWidth = 4; partHeight = 2; numPart = 2; if(interMbPartNum==2) noBlockC = True; calcmv = (interMbPartNum[0]==0 && interSubMbPartNum==0); leftmv = (blockHor>0); end else if(interstate==InterP8x16) begin partWidth = 2; partHeight = 4; numPart = 2; calcmv = (interMbPartNum[1]==0 && interSubMbPartNum==0); leftmv = !(blockVer>0); end else if(interstate==InterP8x8 || interstate==InterP8x8ref0) begin numPart = 4; subMbType = interSubMbTypeVector[interMbPartNum]; numSubPart = numSubMbPart(subMbType); case(subMbType) 0: begin partWidth = 2; partHeight = 2; if(interMbPartNum==3) noBlockC = True; calcmv = (interSubMbPartNum==0); leftmv = (blockHor[0]>0); end 1: begin partWidth = 2; partHeight = 1; if(interSubMbPartNum==2) noBlockC = True; calcmv = (interSubMbPartNum[0]==0); leftmv = True; end 2: begin partWidth = 1; partHeight = 2; calcmv = (interSubMbPartNum[1]==0); leftmv = False; end 3: begin partWidth = 1; partHeight = 1; if(interSubMbPartNum==3) noBlockC = True; calcmv = True; end endcase end else $display( "ERROR Prediction: interProcessStep unexpected interstate"); Bit#(4) refIndex = ((interstate==InterPskip||interstate==InterP8x8ref0) ? 0 : interRefIdxVector[interMbPartNum]); Vector#(3,InterBlockMv) blockABC = replicate(tagged NotInter 0); if( currMbTemp-firstMb==0 && blockHor==0 ) blockABC[0] = (tagged NotInter 0); else blockABC[0] = interLeftVal[blockVer]; if( currMbTemp-firstMbmvhorABC[1] && mvhorABC[0]>mvhorABC[2]) mvhorPred = pack((mvhorABC[1]>mvhorABC[2]) ? mvhorABC[1] : mvhorABC[2]); else if(mvhorABC[0]mvverABC[1] && mvverABC[0]>mvverABC[2]) mvverPred = pack((mvverABC[1]>mvverABC[2]) ? mvverABC[1] : mvverABC[2]); else if(mvverABC[0] 0) interNewestMv <= interNewestMvNext; // Check to see if we are done. if(allDone) interStepCount <= 0; else interStepCount <= 1; $display( "Trace Prediction: interProcessStep final %h %h %h %h %h %h %h",interstate,interStepCount,interMbPartNum,interSubMbPartNum,mvhorfinal,mvverfinal,interNewestMvNext); end endrule rule interIPProcessStep ( interIPStepCount>0 && currMbHorzeroExtend({interIPMbPartNum,interIPSubMbPartNum}) ); Bit#(PicAreaSz) currMbHorTemp = currMbHor+zeroExtend(interCurrMbDiff)-1; Bit#(PicHeightSz) currMbVerTemp = currMbVer; if( currMbHorTemp >= zeroExtend(picWidth) ) begin currMbHorTemp = currMbHorTemp-zeroExtend(picWidth); currMbVerTemp = currMbVerTemp+1; end Bit#(2) blockHor = {interIPMbPartNum[0],interIPSubMbPartNum[0]}; Bit#(2) blockVer = {interIPMbPartNum[1],interIPSubMbPartNum[1]}; Bit#(3) numPart = 1; Bit#(3) numSubPart = 1; Bit#(2) subMbType = 0; if(interstate==InterPskip || interstate==InterP16x16) numPart = 1; else if(interstate==InterP16x8) numPart = 2; else if(interstate==InterP8x16) numPart = 2; else if(interstate==InterP8x8 || interstate==InterP8x8ref0) begin numPart = 4; subMbType = interSubMbTypeVector[interIPMbPartNum]; numSubPart = numSubMbPart(subMbType); end else $display( "ERROR Prediction: interIPProcessStep unexpected interstate"); Bit#(4) refIndex = ((interstate==InterPskip||interstate==InterP8x8ref0) ? 0 : interRefIdxVector[interIPMbPartNum]); Bit#(PicWidthSz) currMbHorT = truncate(currMbHorTemp); Bit#(TAdd#(PicWidthSz,2)) horTemp = {currMbHorT,blockHor}; Bit#(TAdd#(PicHeightSz,4)) verTemp = {currMbVerTemp,blockVer,2'b00}; IPBlockType btTemp = IP16x16; if(interstate==InterPskip || interstate==InterP16x16) btTemp = IP16x16; else if(interstate==InterP16x8) btTemp = IP16x8; else if(interstate==InterP8x16) btTemp = IP8x16; else begin case(subMbType) 0: btTemp = IP8x8; 1: btTemp = IP8x4; 2: btTemp = IP4x8; 3: btTemp = IP4x4; endcase end Bit#(14) mvhorTemp = tpl_1(interMvFile.sub({interIPMbPartNum,interIPSubMbPartNum})); Bit#(12) mvverTemp = tpl_2(interMvFile.sub({interIPMbPartNum,interIPSubMbPartNum})); if(interIPStepCount == 1) begin if(!(interstate==InterP8x8 || interstate==InterP8x8ref0)) begin numPart = 4; Bit#(2) interIPMbPartNumTemp = interIPMbPartNum; if(btTemp==IP16x16) interIPMbPartNumTemp = 0; else if(btTemp==IP16x8 && interIPMbPartNumTemp[0]==1) interIPMbPartNumTemp = interIPMbPartNumTemp-1; else if(btTemp==IP8x16 && interIPMbPartNumTemp[1]==1) interIPMbPartNumTemp = interIPMbPartNumTemp-2; refIndex = ((interstate==InterPskip||interstate==InterP8x8ref0) ? 0 : interRefIdxVector[interIPMbPartNumTemp]); btTemp = IP8x8; mvhorTemp = tpl_1(interMvFile.sub({interIPMbPartNumTemp,2'b00})); mvverTemp = tpl_2(interMvFile.sub({interIPMbPartNumTemp,2'b00})); interpolator.request(tagged IPLuma {refIdx:refIndex,hor:horTemp,ver:verTemp,mvhor:mvhorTemp,mvver:mvverTemp,bt:btTemp}); end else interpolator.request(tagged IPLuma {refIdx:refIndex,hor:horTemp,ver:verTemp,mvhor:mvhorTemp,mvver:mvverTemp,bt:btTemp}); end else interpolator.request(tagged IPChroma {refIdx:refIndex,uv:interIPStepCount[0],hor:horTemp,ver:truncate(verTemp>>1),mvhor:mvhorTemp,mvver:mvverTemp,bt:btTemp}); if(interIPSubMbPartNum >= truncate(numSubPart-1)) begin interIPSubMbPartNum <= 0; if(interIPMbPartNum >= truncate(numPart-1)) begin interIPMbPartNum <= 0; interIPStepCount <= interIPStepCount+1; end else begin if(btTemp == IP16x8) interIPMbPartNum <= 2; else interIPMbPartNum <= interIPMbPartNum+1; end end else begin if(subMbType == 1) interIPSubMbPartNum <= 2; else interIPSubMbPartNum <= interIPSubMbPartNum+1; end $display( "Trace Prediction: interIPProcessStep %h %h %h %h %h %h %h %h %h %h", interstate, interIPStepCount, interIPMbPartNum, interIPSubMbPartNum, refIndex, horTemp, verTemp, mvhorTemp, mvverTemp, pack(btTemp)); endrule rule interDone ( interstate!=Start && interReqCount==0 && interRespCount==0 && interStepCount==0 && interIPStepCount==0 ); interstate <= Start; //$display( "Trace Prediction: interOutputTransfer %h %h", interstate, interOutputCount); endrule rule interOutputTransfer ( True ); predictedfifo.enq(interpolator.first()); interpolator.deq(); //$display( "Trace Prediction: interOutputTransfer %h %h", interstate, interOutputCount); endrule // intra prediction rules rule intraSendReq ( intraReqCount>0 && currMbHor0 && currMb-firstMb>zeroExtend(picWidth)) temp = {(temp2-1),2'b11}; else noMoreReq = 1; end else if(intraReqCount==6) begin if((currMbHor+1)0 && currMb-firstMb>zeroExtend(picWidth)) temp = {(temp2-1),2'b11}; else noMoreReq = 1; end else noMoreReq = 1; end if(noMoreReq == 0) begin intraMemReqQ.enq(tagged LoadReq temp); intraReqCount <= intraReqCount+1; //$display( "TRACE Prediction: intraSendReq addr %0d",temp);/////////////////////// end else intraReqCount <= 0; $display( "Trace Prediction: intraSendReq"); endrule rule intraReceiveNoResp ( intraRespCount>0 && currMbHor0 && intraRespCount<7 && currMbHor0 && currMb-firstMb>zeroExtend(picWidth))) noMoreResp = 1; end else intraTopVal <= update(intraTopVal, intraRespCount-1, data[31:0]); intraTopValChroma0 <= update(intraTopValChroma0, temp2bit, data[47:32]); intraTopValChroma1 <= update(intraTopValChroma1, temp2bit, data[63:48]); end else if(intraRespCount==5) begin if((currMbHor+1)0 && currMb-firstMb>zeroExtend(picWidth))) noMoreResp = 1; end else begin Bit#(40) temp2 = intraLeftVal[0]; intraLeftVal <= update(intraLeftVal, 0, {temp2[39:8],data[31:24]}); intraLeftValChroma0 <= update(intraLeftValChroma0, 0, data[47:40]); intraLeftValChroma1 <= update(intraLeftValChroma1, 0, data[63:56]); noMoreResp = 1; end end else begin Bit#(40) temp2 = intraLeftVal[0]; intraLeftVal <= update(intraLeftVal, 0, {temp2[39:8],data[31:24]}); intraLeftValChroma0 <= update(intraLeftValChroma0, 0, data[47:40]); intraLeftValChroma1 <= update(intraLeftValChroma1, 0, data[63:56]); noMoreResp = 1; end intraMemRespQ.deq(); //$display( "TRACE Prediction: intraReceiveResp data %h",data);/////////////////////// if(noMoreResp == 0) intraRespCount <= intraRespCount+1; else begin intraRespCount <= 0; intraStepCount <= 1; blockNum <= 0; pixelNum <= 0; interOutBlockMvfifo.enq(tagged NotInter 1); end $display( "Trace Prediction: intraReceiveResp"); endrule rule intraPredTypeStep ( intraStepCount==1 && !nextoutputfifo.notEmpty()); Bit#(2) blockHor = {blockNum[2],blockNum[0]}; Bit#(2) blockVer = {blockNum[3],blockNum[1]}; Bit#(4) topType = select(intra4x4typeTop, blockHor); Bit#(4) leftType; if(currMbHor!=0 || blockNum!=0) leftType = select(intra4x4typeLeft, blockVer); else begin leftType = 15; intra4x4typeLeft <= replicate(15); end if(intrastate!=Intra4x4) begin intraStepCount <= intraStepCount+1; nextoutputfifo.enq(NonSkipMB); end else begin Bit#(1) topAvailable; Bit#(1) leftAvailable; if(topType==15 || (topType==14 && ppsconstrained_intra_pred_flag==1)) topAvailable = 0; else topAvailable = 1; if(leftType==15 || (leftType==14 && ppsconstrained_intra_pred_flag==1)) leftAvailable = 0; else leftAvailable = 1; Bit#(4) predType = 0; Bit#(4) remType = rem_intra4x4_pred_mode.first(); Bit#(4) curType = 0; rem_intra4x4_pred_mode.deq(); if(topAvailable==0 || leftAvailable==0) predType = 2; else begin Bit#(4) topType2 = topType; Bit#(4) leftType2 = leftType; if(topType>8) topType2 = 2; if(leftType>8) leftType2 = 2; if(topType2 > leftType2) predType = leftType2; else predType = topType2; end if(remType[3] == 1) curType = predType; else if(remType < predType) curType = remType; else curType = remType+1; cur_intra4x4_pred_mode <= curType; intraStepCount <= intraStepCount+1; if(blockNum == 15) nextoutputfifo.enq(tagged Intra4x4PlusChroma); else nextoutputfifo.enq(tagged Intra4x4); $display( "TRACE Prediction: intraPredTypeStep currMbHor currMbVer blockNum topType leftType predType remType curType %0d %0d %0d %0d %0d %0d %0d %0d",currMbHor,currMbVer,blockNum,topType,leftType,predType,remType,curType);////////////////// end //$display( "Trace Prediction: intraPredTypeStep"); endrule rule intraProcessStep ( intraStepCount>1 ); $display( "TRACE Prediction: intraProcessStep %0d %0d", blockNum, pixelNum);//////////////////// //$display( "TRACE Prediction: intraProcessStep intraTopVal %h %h %h %h %h",intraTopVal[4],intraTopVal[3],intraTopVal[2],intraTopVal[1],intraTopVal[0]);///////////////// Bit#(1) outFlag = 0; Bit#(4) nextIntraStepCount = intraStepCount+1; Bit#(2) blockHor = {blockNum[2],blockNum[0]}; Bit#(2) blockVer = {blockNum[3],blockNum[1]}; Bit#(2) pixelVer = {pixelNum[3],pixelNum[2]}; Vector#(4,Bit#(8)) predVector = replicate(0); Bit#(4) topType = select(intra4x4typeTop, blockHor); Bit#(4) leftType = select(intra4x4typeLeft, blockVer); Bit#(1) topAvailable; Bit#(1) leftAvailable; if(topType==15 || (topType==14 && ppsconstrained_intra_pred_flag==1)) topAvailable = 0; else topAvailable = 1; if(leftType==15 || (leftType==14 && ppsconstrained_intra_pred_flag==1)) leftAvailable = 0; else leftAvailable = 1; if(blockNum==0 && pixelNum==0 && intraChromaFlag==0) begin intraChromaTopAvailable <= topAvailable; intraChromaLeftAvailable <= leftAvailable; end if(intrastate==Intra4x4 && intraChromaFlag==0) begin if(intraStepCount==2) begin outFlag = 1; Bit#(40) leftValSet = select(intraLeftVal,blockVer); Bit#(32) topMidValSet = select(intraTopVal,blockHor); Bit#(32) topRightValSet = select(intraTopVal,{1'b0,blockHor}+1); Bit#(72) topValSet; if((blockNum[3:2]==3 && blockNum[0]==1) || blockNum[1:0]==3) topValSet = {topMidValSet[31:24],topMidValSet[31:24],topMidValSet[31:24],topMidValSet[31:24],topMidValSet,leftValSet[7:0]}; else topValSet = {topRightValSet,topMidValSet,leftValSet[7:0]}; $display( "TRACE Prediction: intraProcessStep intra4x4 %0d %0d %h %h", cur_intra4x4_pred_mode, blockNum, leftValSet, topValSet);//////////////////// Bit#(4) topSelect1 = 0; Bit#(4) topSelect2 = 0; Bit#(4) topSelect3 = 0; Bit#(3) leftSelect1 = 0; Bit#(3) leftSelect2 = 0; Bit#(3) leftSelect3 = 0; Bit#(10) tempVal1 = 0; Bit#(10) tempVal2 = 0; Bit#(10) tempVal3 = 0; case(cur_intra4x4_pred_mode) 0://vertical begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin topSelect1 = fromInteger(pixelHor); Bit#(8) topVal = intra4x4SelectTop(topValSet,topSelect1); predVector[pixelHor] = topVal; end end 1://horizontal begin leftSelect1 = zeroExtend(pixelVer); Bit#(8) leftVal = intra4x4SelectLeft(leftValSet,leftSelect1); for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) predVector[pixelHor] = leftVal; end 2://dc begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin Bit#(10) tempTopSum = zeroExtend(topValSet[15:8])+zeroExtend(topValSet[23:16])+zeroExtend(topValSet[31:24])+zeroExtend(topValSet[39:32]) + 2; Bit#(10) tempLeftSum = zeroExtend(leftValSet[15:8])+zeroExtend(leftValSet[23:16])+zeroExtend(leftValSet[31:24])+zeroExtend(leftValSet[39:32]) + 2; Bit#(11) tempTotalSum = zeroExtend(tempTopSum)+zeroExtend(tempLeftSum); Bit#(8) topSum = tempTopSum[9:2]; Bit#(8) leftSum = tempLeftSum[9:2]; Bit#(8) totalSum = tempTotalSum[10:3]; if(topAvailable==1 && leftAvailable==1) predVector[pixelHor] = totalSum; else if(topAvailable==1) predVector[pixelHor] = topSum; else if(leftAvailable==1) predVector[pixelHor] = leftSum; else predVector[pixelHor] = 8'b10000000; end end 3://diagonal down left begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin Bit#(4) selectNum = fromInteger(pixelHor)+zeroExtend(pixelVer); if(pixelHor==3 && pixelVer==3) begin topSelect1 = 6; topSelect2 = 7; topSelect3 = 7; end else begin topSelect1 = selectNum; topSelect2 = selectNum+1; topSelect3 = selectNum+2; end tempVal1 = zeroExtend(intra4x4SelectTop(topValSet,topSelect1)); tempVal2 = zeroExtend(intra4x4SelectTop(topValSet,topSelect2)); tempVal3 = zeroExtend(intra4x4SelectTop(topValSet,topSelect3)); Bit#(10) predVal = tempVal1 + (tempVal2<<1) + tempVal3 + 2; predVector[pixelHor] = predVal[9:2]; end end 4://diagonal down right begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin if(fromInteger(pixelHor) > pixelVer) begin topSelect3 = fromInteger(pixelHor)-zeroExtend(pixelVer); topSelect2 = topSelect3-1; topSelect1 = topSelect3-2; tempVal1 = zeroExtend(intra4x4SelectTop(topValSet,topSelect1)); tempVal2 = zeroExtend(intra4x4SelectTop(topValSet,topSelect2)); tempVal3 = zeroExtend(intra4x4SelectTop(topValSet,topSelect3)); end else if(fromInteger(pixelHor) < pixelVer) begin leftSelect3 = zeroExtend(pixelVer)-fromInteger(pixelHor); leftSelect2 = leftSelect3-1; leftSelect1 = leftSelect3-2; tempVal1 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect1)); tempVal2 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect2)); tempVal3 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect3)); end else begin leftSelect1 = 0; leftSelect2 = -1; topSelect1 = 0; tempVal1 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect1)); tempVal2 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect2)); tempVal3 = zeroExtend(intra4x4SelectTop(topValSet,topSelect1)); end Bit#(10) predVal = tempVal1 + (tempVal2<<1) + tempVal3 + 2; predVector[pixelHor] = predVal[9:2]; end end 5://vertical right begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin Bit#(4) tempPixelHor = fromInteger(pixelHor); Bit#(4) zVR = (tempPixelHor<<1)-zeroExtend(pixelVer); if(zVR<=6 && zVR>=0) begin topSelect3 = fromInteger(pixelHor)-zeroExtend(pixelVer>>1); topSelect2 = topSelect3-1; if(zVR==1 || zVR==3 || zVR==5) topSelect1 = topSelect3-2; else topSelect1 = topSelect3; tempVal1 = zeroExtend(intra4x4SelectTop(topValSet,topSelect1)); tempVal2 = zeroExtend(intra4x4SelectTop(topValSet,topSelect2)); tempVal3 = zeroExtend(intra4x4SelectTop(topValSet,topSelect3)); end else if(zVR==-1) begin leftSelect1 = 0; leftSelect2 = -1; topSelect1 = 0; tempVal1 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect1)); tempVal2 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect2)); tempVal3 = zeroExtend(intra4x4SelectTop(topValSet,topSelect1)); end else begin leftSelect1 = zeroExtend(pixelVer)-1; leftSelect2 = leftSelect1-1; leftSelect3 = leftSelect1-2; tempVal1 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect1)); tempVal2 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect2)); tempVal3 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect3)); end Bit#(10) predVal = tempVal1 + (tempVal2<<1) + tempVal3 + 2; predVector[pixelHor] = predVal[9:2]; end end 6://horizontal down begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin Bit#(4) tempPixelVer = zeroExtend(pixelVer); Bit#(4) zHD = (tempPixelVer<<1)-fromInteger(pixelHor); if(zHD<=6 && zHD>=0) begin leftSelect3 = zeroExtend(pixelVer)-fromInteger(pixelHor/2); leftSelect2 = leftSelect3-1; if(zHD==1 || zHD==3 || zHD==5) leftSelect1 = leftSelect3-2; else leftSelect1 = leftSelect3; tempVal1 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect1)); tempVal2 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect2)); tempVal3 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect3)); end else if(zHD==-1) begin leftSelect1 = 0; leftSelect2 = -1; topSelect1 = 0; tempVal1 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect1)); tempVal2 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect2)); tempVal3 = zeroExtend(intra4x4SelectTop(topValSet,topSelect1)); end else begin topSelect1 = fromInteger(pixelHor)-1; topSelect2 = topSelect1-1; topSelect3 = topSelect1-2; tempVal1 = zeroExtend(intra4x4SelectTop(topValSet,topSelect1)); tempVal2 = zeroExtend(intra4x4SelectTop(topValSet,topSelect2)); tempVal3 = zeroExtend(intra4x4SelectTop(topValSet,topSelect3)); end Bit#(10) predVal = tempVal1 + (tempVal2<<1) + tempVal3 + 2; predVector[pixelHor] = predVal[9:2]; end end 7://vertical left begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin topSelect1 = fromInteger(pixelHor)+zeroExtend(pixelVer>>1); topSelect2 = topSelect1+1; if(pixelVer==1 || pixelVer==3) topSelect3 = topSelect1+2; else topSelect3 = topSelect1; tempVal1 = zeroExtend(intra4x4SelectTop(topValSet,topSelect1)); tempVal2 = zeroExtend(intra4x4SelectTop(topValSet,topSelect2)); tempVal3 = zeroExtend(intra4x4SelectTop(topValSet,topSelect3)); Bit#(10) predVal = tempVal1 + (tempVal2<<1) + tempVal3 + 2; predVector[pixelHor] = predVal[9:2]; end end 8://horizontal up begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin Bit#(4) tempPixelVer = zeroExtend(pixelVer); Bit#(4) zHU = (tempPixelVer<<1)+fromInteger(pixelHor); if(zHU<=4) begin leftSelect1 = zeroExtend(pixelVer)+fromInteger(pixelHor/2); leftSelect2 = leftSelect1+1; if(zHU==1 || zHU==3) leftSelect3 = leftSelect1+2; else leftSelect3 = leftSelect1; end else begin if(zHU==5) leftSelect1 = 2; else leftSelect1 = 3; leftSelect2 = 3; leftSelect3 = 3; end tempVal1 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect1)); tempVal2 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect2)); tempVal3 = zeroExtend(intra4x4SelectLeft(leftValSet,leftSelect3)); Bit#(10) predVal = tempVal1 + (tempVal2<<1) + tempVal3 + 2; predVector[pixelHor] = predVal[9:2]; end end default: $display( "ERROR Prediction: intraProcessStep intra4x4 unknown cur_intra4x4_pred_mode"); endcase end else $display( "ERROR Prediction: intraProcessStep intra4x4 unknown intraStepCount"); end else if(intrastate==Intra16x16 && intraChromaFlag==0) begin //$display( "TRACE Prediction: intraProcessStep intra16x16 %0d %0d %0d %h", intra16x16_pred_mode, currMb, blockNum, select(intraTopVal,blockHor));///////////////// case(intra16x16_pred_mode) 0://vertical begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin Bit#(32) topValSet = select(intraTopVal,blockHor); Bit#(8) topVal = select32to8(topValSet,fromInteger(pixelHor)); predVector[pixelHor] = topVal; end outFlag = 1; end 1://horizontal begin Bit#(40) leftValSet = select(intraLeftVal,blockVer); Bit#(8) leftVal = intra4x4SelectLeft(leftValSet,zeroExtend(pixelVer)); for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) predVector[pixelHor] = leftVal; outFlag = 1; end 2://dc begin case(intraStepCount) 2: begin if(topAvailable == 1) begin Bit#(32) topValSet = select(intraTopVal,0); intraSumA <= zeroExtend(topValSet[7:0])+zeroExtend(topValSet[15:8])+zeroExtend(topValSet[23:16])+zeroExtend(topValSet[31:24]); end else begin intraSumA <= 0; nextIntraStepCount = 6; end end 3: begin Bit#(32) topValSet = select(intraTopVal,1); intraSumA <= intraSumA+zeroExtend(topValSet[7:0])+zeroExtend(topValSet[15:8])+zeroExtend(topValSet[23:16])+zeroExtend(topValSet[31:24]); end 4: begin Bit#(32) topValSet = select(intraTopVal,2); intraSumA <= intraSumA+zeroExtend(topValSet[7:0])+zeroExtend(topValSet[15:8])+zeroExtend(topValSet[23:16])+zeroExtend(topValSet[31:24]); end 5: begin Bit#(32) topValSet = select(intraTopVal,3); intraSumA <= intraSumA+zeroExtend(topValSet[7:0])+zeroExtend(topValSet[15:8])+zeroExtend(topValSet[23:16])+zeroExtend(topValSet[31:24])+8; end 6: begin if(leftAvailable == 1) begin Bit#(40) leftValSet = select(intraLeftVal,0); intraSumA <= intraSumA+zeroExtend(leftValSet[15:8])+zeroExtend(leftValSet[23:16])+zeroExtend(leftValSet[31:24])+zeroExtend(leftValSet[39:32]); end else nextIntraStepCount = 10; end 7: begin Bit#(40) leftValSet = select(intraLeftVal,1); intraSumA <= intraSumA+zeroExtend(leftValSet[15:8])+zeroExtend(leftValSet[23:16])+zeroExtend(leftValSet[31:24])+zeroExtend(leftValSet[39:32]); end 8: begin Bit#(40) leftValSet = select(intraLeftVal,2); intraSumA <= intraSumA+zeroExtend(leftValSet[15:8])+zeroExtend(leftValSet[23:16])+zeroExtend(leftValSet[31:24])+zeroExtend(leftValSet[39:32]); end 9: begin Bit#(40) leftValSet = select(intraLeftVal,3); intraSumA <= intraSumA+zeroExtend(leftValSet[15:8])+zeroExtend(leftValSet[23:16])+zeroExtend(leftValSet[31:24])+zeroExtend(leftValSet[39:32])+8; end 10: begin if(leftAvailable == 1 && topAvailable == 1) intraSumA <= intraSumA >> 5; else if(leftAvailable == 1 || topAvailable == 1) intraSumA <= intraSumA >> 4; else intraSumA <= 128; end 11: begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) predVector[pixelHor] = intraSumA[7:0]; outFlag = 1; end default: $display( "ERROR Prediction: intraProcessStep intra16x16 DC unknown intraStepCount"); endcase end 3://plane begin if(intraStepCount == 2) begin Bit#(32) topValSet = select(intraTopVal,3); Bit#(8) topVal = select32to8(topValSet,3); Bit#(40) leftValSet = select(intraLeftVal,3); Bit#(8) leftVal = intra4x4SelectLeft(leftValSet,3); Bit#(13) tempVal = zeroExtend(topVal) + zeroExtend(leftVal); intraSumA <= tempVal << 4; intraSumB <= 0; intraSumC <= 0; end else if(intraStepCount < 11) begin Bit#(4) xyPlusOne = intraStepCount-2; Bit#(4) xyPlusEight = intraStepCount+5; Bit#(4) sixMinusXY = 9-intraStepCount; Bit#(32) topValSet1 = select(intraTopVal,xyPlusEight[3:2]); Bit#(8) topVal1 = select32to8(topValSet1,xyPlusEight[1:0]); Bit#(40) leftValSet1 = select(intraLeftVal,xyPlusEight[3:2]); Bit#(8) leftVal1 = intra4x4SelectLeft(leftValSet1,zeroExtend(xyPlusEight[1:0])); Bit#(32) topValSet2=0; Bit#(8) topVal2; Bit#(40) leftValSet2; Bit#(8) leftVal2; if(intraStepCount==10) begin leftValSet2 = select(intraLeftVal,0); leftVal2 = intra4x4SelectLeft(leftValSet2,-1); topVal2 = leftVal2; end else begin topValSet2 = select(intraTopVal,sixMinusXY[3:2]); topVal2 = select32to8(topValSet2,sixMinusXY[1:0]); leftValSet2 = select(intraLeftVal,sixMinusXY[3:2]); leftVal2 = intra4x4SelectLeft(leftValSet2,zeroExtend(sixMinusXY[1:0])); end Bit#(15) diffH = zeroExtend(topVal1) - zeroExtend(topVal2); Bit#(15) diffV = zeroExtend(leftVal1) - zeroExtend(leftVal2); intraSumB <= intraSumB + (zeroExtend(xyPlusOne) * diffH); intraSumC <= intraSumC + (zeroExtend(xyPlusOne) * diffV); end else if(intraStepCount == 11) begin Bit#(18) tempSumB = (5*signExtend(intraSumB)) + 32; Bit#(18) tempSumC = (5*signExtend(intraSumC)) + 32; intraSumB <= signExtend(tempSumB[17:6]); intraSumC <= signExtend(tempSumC[17:6]); end else if(intraStepCount == 12) begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin Bit#(5) positionHor = {1'b0,blockHor,fromInteger(pixelHor)}; Bit#(5) positionVer = {1'b0,blockVer,pixelVer}; Bit#(16) tempProductB = signExtend(intraSumB) * signExtend(positionHor-7); Bit#(16) tempProductC = signExtend(intraSumC) * signExtend(positionVer-7); Bit#(16) tempTotal = tempProductB + tempProductC + zeroExtend(intraSumA) + 16; if(tempTotal[15]==1) predVector[pixelHor] = 0; else if(tempTotal[14:5] > 255) predVector[pixelHor] = 255; else predVector[pixelHor] = tempTotal[12:5]; end outFlag = 1; end else $display( "ERROR Prediction: intraProcessStep intra16x16 plane unknown intraStepCount"); end endcase end else if(intraChromaFlag==1) begin //$display( "TRACE Prediction: intraProcessStep intraChroma %0d %0d %0d %0d %0d %0d %h %h %h %h %h %h %h %h",intra_chroma_pred_mode.first(),intraChromaTopAvailable,intraChromaLeftAvailable,currMb,blockNum,pixelNum,pack(intraLeftValChroma0),pack(intraTopValChroma0),pack(intraLeftValChroma1),pack(intraTopValChroma1),intraLeftValChroma0[0],intraTopValChroma0[3][15:8],intraLeftValChroma1[0],intraTopValChroma1[3][15:8]);/////////////////// Vector#(9,Bit#(8)) tempLeftVec; Vector#(4,Bit#(16)) tempTopVec; if(blockNum[2] == 0) begin tempLeftVec = intraLeftValChroma0; tempTopVec = intraTopValChroma0; end else begin tempLeftVec = intraLeftValChroma1; tempTopVec = intraTopValChroma1; end case(intra_chroma_pred_mode.first()) 0://dc begin if(intraStepCount == 2) begin Bit#(1) useTop=0; Bit#(1) useLeft=0; if(blockNum[1:0] == 0 || blockNum[1:0] == 3) begin useTop = intraChromaTopAvailable; useLeft = intraChromaLeftAvailable; end else if(blockNum[1:0] == 1) begin if(intraChromaTopAvailable == 1) useTop = 1; else if(intraChromaLeftAvailable == 1) useLeft = 1; end else if(blockNum[1:0] == 2) begin if(intraChromaLeftAvailable == 1) useLeft = 1; else if(intraChromaTopAvailable == 1) useTop = 1; end else $display( "ERROR Prediction: intraProcessStep intraChroma dc unknown blockNum"); Bit#(10) topSum; Bit#(10) leftSum; Bit#(11) totalSum; if(blockHor[0] == 0) topSum = zeroExtend(tempTopVec[0][15:8])+zeroExtend(tempTopVec[0][7:0])+zeroExtend(tempTopVec[1][15:8])+zeroExtend(tempTopVec[1][7:0])+2; else topSum = zeroExtend(tempTopVec[2][15:8])+zeroExtend(tempTopVec[2][7:0])+zeroExtend(tempTopVec[3][15:8])+zeroExtend(tempTopVec[3][7:0])+2; if(blockVer[0] == 0) leftSum = zeroExtend(tempLeftVec[1])+zeroExtend(tempLeftVec[2])+zeroExtend(tempLeftVec[3])+zeroExtend(tempLeftVec[4])+2; else leftSum = zeroExtend(tempLeftVec[5])+zeroExtend(tempLeftVec[6])+zeroExtend(tempLeftVec[7])+zeroExtend(tempLeftVec[8])+2; totalSum = zeroExtend(topSum) + zeroExtend(leftSum); if(useTop==1 && useLeft==1) intraSumA <= zeroExtend(totalSum[10:3]); else if(useTop==1) intraSumA <= zeroExtend(topSum[9:2]); else if(useLeft==1) intraSumA <= zeroExtend(leftSum[9:2]); else intraSumA <= zeroExtend(8'b10000000); end else if(intraStepCount == 3) begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) predVector[pixelHor] = intraSumA[7:0]; outFlag = 1; end else $display( "ERROR Prediction: intraProcessStep intraChroma dc unknown intraStepCount"); end 1://horizontal begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin Bit#(4) tempLeftIdx = {1'b0,blockVer[0],pixelVer} + 1; predVector[pixelHor] = select(tempLeftVec,tempLeftIdx); end outFlag = 1; end 2://vertical begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin Bit#(2) pixelHorTemp = fromInteger(pixelHor); Bit#(16) tempTopVal = select(tempTopVec,{blockHor[0],pixelHorTemp[1]}); if(pixelHorTemp[0] == 0) predVector[pixelHor] = tempTopVal[7:0]; else predVector[pixelHor] = tempTopVal[15:8]; end outFlag = 1; end 3://plane begin if(intraStepCount == 2) begin Bit#(16) topValSet = tempTopVec[3]; Bit#(8) topVal = topValSet[15:8]; Bit#(8) leftVal = tempLeftVec[8]; Bit#(13) tempVal = zeroExtend(topVal) + zeroExtend(leftVal); intraSumA <= tempVal << 4; intraSumB <= 0; intraSumC <= 0; end else if(intraStepCount < 7) begin Bit#(3) xyPlusOne = truncate(intraStepCount)-2; Bit#(3) xyPlusFour = truncate(intraStepCount)+1; Bit#(4) twoMinusXY = 5-intraStepCount; Bit#(16) topValSet1 = select(tempTopVec,xyPlusFour[2:1]); Bit#(8) topVal1 = select16to8(topValSet1,xyPlusFour[0]); Bit#(4) tempLeftIdx1 = {1'b0,xyPlusFour} + 1; Bit#(8) leftVal1 = select(tempLeftVec,tempLeftIdx1); Bit#(16) topValSet2 = select(tempTopVec,twoMinusXY[2:1]); Bit#(8) topVal2; Bit#(8) leftVal2 = select(tempLeftVec,twoMinusXY+1); if(intraStepCount==6) topVal2 = leftVal2; else topVal2 = select16to8(topValSet2,twoMinusXY[0]); Bit#(15) diffH = zeroExtend(topVal1) - zeroExtend(topVal2); Bit#(15) diffV = zeroExtend(leftVal1) - zeroExtend(leftVal2); intraSumB <= intraSumB + (zeroExtend(xyPlusOne) * diffH); intraSumC <= intraSumC + (zeroExtend(xyPlusOne) * diffV); Int#(15) tempDisplayH = unpack(zeroExtend(xyPlusOne) * diffH); Int#(15) tempDisplayV = unpack(zeroExtend(xyPlusOne) * diffV); //$display( "TRACE Prediction: intraProcessStep intraChroma plane partH partV %0d %0d",tempDisplayH,tempDisplayV);//////////////////// end else if(intraStepCount == 7) begin Int#(15) tempDisplayH = unpack(intraSumB); Int#(15) tempDisplayV = unpack(intraSumC); //$display( "TRACE Prediction: intraProcessStep intraChroma plane H V %0d %0d",tempDisplayH,tempDisplayV);//////////////////// Bit#(19) tempSumB = (34*signExtend(intraSumB)) + 32; Bit#(19) tempSumC = (34*signExtend(intraSumC)) + 32; intraSumB <= signExtend(tempSumB[18:6]); intraSumC <= signExtend(tempSumC[18:6]); end else if(intraStepCount == 8) begin for(Integer pixelHor=0; pixelHor<4; pixelHor=pixelHor+1) begin Bit#(4) positionHor = {1'b0,blockHor[0],fromInteger(pixelHor)}; Bit#(4) positionVer = {1'b0,blockVer[0],pixelVer}; Bit#(17) tempProductB = signExtend(intraSumB) * signExtend(positionHor-3); Bit#(17) tempProductC = signExtend(intraSumC) * signExtend(positionVer-3); Bit#(17) tempTotal = tempProductB + tempProductC + zeroExtend(intraSumA) + 16; if(tempTotal[16]==1) predVector[pixelHor] = 0; else if(tempTotal[15:5] > 255) predVector[pixelHor] = 255; else predVector[pixelHor] = tempTotal[12:5]; end outFlag = 1; end else $display( "ERROR Prediction: intraProcessStep intraChroma plane unknown intraStepCount"); end endcase end else $display( "ERROR Prediction: intraProcessStep unknown intrastate"); if(outFlag==1) begin predictedfifo.enq(predVector); pixelNum <= pixelNum+4; if(pixelNum == 12) begin if(intraChromaFlag==0) begin blockNum <= blockNum+1; if(blockNum == 15) begin intraChromaFlag <= 1; intraStepCount <= 2; end else if(intrastate==Intra4x4) intraStepCount <= 1; end else begin if(blockNum == 7) begin blockNum <= 0; intraChromaFlag <= 0; intraStepCount <= 0; intra_chroma_pred_mode.deq(); end else begin blockNum <= blockNum+1; if(intra_chroma_pred_mode.first()==0) intraStepCount <= 2; else if(blockNum==3) intraStepCount <= 2; end end end end else intraStepCount <= nextIntraStepCount; //$display( "Trace Prediction: intraProcessStep"); endrule interface Client mem_client_intra; interface Get request = fifoToGet(intraMemReqQ); interface Put response = fifoToPut(intraMemRespQ); endinterface interface Client mem_client_inter; interface Get request = fifoToGet(interMemReqQ); interface Put response = fifoToPut(interMemRespQ); endinterface interface Client mem_client_buffer = interpolator.mem_client; interface Put ioin = fifoToPut(infifo); interface Put ioin_InverseTrans = fifoToPut(infifo_ITB); interface Get ioout = fifoToGet(outfifo); endmodule endpackage