URL
https://opencores.org/ocsvn/bluespec-h264/bluespec-h264/trunk
Subversion Repositories bluespec-h264
[/] [bluespec-h264/] [trunk/] [src/] [mkEntropyDec.bsv] - Rev 13
Go to most recent revision | Compare with Previous | Blame | View Log
//**********************************************************************
// Entropy Decoder implementation
//----------------------------------------------------------------------
//
//
package mkEntropyDec;
import H264Types::*;
import ExpGolomb::*;
import CAVLC::*;
import ICalc_nC::*;
import mkCalc_nC::*;
import IEntropyDec::*;
import FIFO::*;
import Connectable::*;
import GetPut::*;
import ClientServer::*;
//-----------------------------------------------------------
// Local Datatypes
//-----------------------------------------------------------
typedef union tagged
{
void Start; //special state that initializes the process.
void NewUnit; //special state that checks the NAL unit type.
Bit#(5) CodedSlice; //decodes a type of NAL unit
void SEI; //decodes a type of NAL unit
Bit#(5) SPS; //decodes a type of NAL unit
Bit#(5) PPS; //decodes a type of NAL unit
void AUD; //decodes a type of NAL unit
void EndSequence; //decodes a type of NAL unit
void EndStream; //decodes a type of NAL unit
void Filler; //decodes a type of NAL unit
Bit#(5) SliceData; //decodes slice data (part of a CodedSlice NAL unit)
Bit#(5) MacroblockLayer; //decodes macroblock layer (part of a CodedSlice NAL unit)
Bit#(5) MbPrediction; //decodes macroblock prediction (part of a CodedSlice NAL unit)
Bit#(5) SubMbPrediction; //decodes sub-macroblock prediction (part of a CodedSlice NAL unit)
Bit#(5) ResidualBlock; //decodes residual block (part of a CodedSlice NAL unit)
}
State deriving(Eq,Bits);
//-----------------------------------------------------------
// Helper functions
function MbType mbtype_convert( Bit#(5) in_mb_type, Bit#(4) in_slice_type );//converts mb_type syntax element to MbType type
Bit#(5) tempmb = in_mb_type;
if(in_slice_type == 2 || in_slice_type == 7)//I slice
tempmb = in_mb_type+5;
case ( tempmb )
0: return P_L0_16x16;
1: return P_L0_L0_16x8;
2: return P_L0_L0_8x16;
3: return P_8x8;
4: return P_8x8ref0;
5: return I_NxN;
30: return I_PCM;
default:
begin
Bit#(5) tempmb16x16 = tempmb-6;
Bit#(2) tempv1 = tempmb16x16[1:0];
Bit#(2) tempv2;
Bit#(1) tempv3;
if(tempmb16x16 < 12)
begin
tempv3 = 0;
tempv2 = tempmb16x16[3:2];
end
else
begin
tempv3 = 1;
tempv2 = tempmb16x16[3:2]+1;
end
return I_16x16{intra16x16PredMode:tempv1, codedBlockPatternChroma:tempv2, codedBlockPatternLuma:tempv3};
end
endcase
endfunction
//-----------------------------------------------------------
// Entropy Decoder Module
//-----------------------------------------------------------
(* synthesize *)
module mkEntropyDec( IEntropyDec );
FIFO#(NalUnwrapOT) infifo <- mkSizedFIFO(entropyDec_infifo_size);
FIFO#(EntropyDecOT) outfifo <- mkFIFO;
FIFO#(EntropyDecOT_InverseTrans) outfifo_ITB <- mkFIFO;
Reg#(State) state <- mkReg(Start);
Reg#(Bit#(2)) nalrefidc <- mkReg(0);
Reg#(Bit#(5)) nalunittype <- mkReg(0);
Reg#(Buffer) buffer <- mkReg(0);
Reg#(Bufcount) bufcount <- mkReg(0);
//saved syntax elements
Reg#(Bit#(5)) spsseq_parameter_set_id <- mkReg(0);
Reg#(Bit#(5)) spslog2_max_frame_num <- mkReg(0);
Reg#(Bit#(5)) spslog2_max_pic_order_cnt_lsb <- mkReg(0);
Reg#(Bit#(2)) spspic_order_cnt_type <- mkReg(0);
Reg#(Bit#(1)) spsdelta_pic_order_always_zero_flag <- mkReg(0);
Reg#(Bit#(8)) spsnum_ref_frames_in_pic_order_cnt_cycle <- mkReg(0);
Reg#(Bit#(8)) ppspic_parameter_set_id <- mkReg(0);
Reg#(Bit#(1)) ppspic_order_present_flag <- mkReg(0);
Reg#(Bit#(1)) ppsdeblocking_filter_control_present_flag <- mkReg(0);
Reg#(Bit#(4)) shslice_type <- mkReg(0);
Reg#(Bit#(3)) shdmemory_management_control_operation <- mkReg(0);
Reg#(MbType) sdmmbtype <- mkReg(I_NxN);
Reg#(Bit#(4)) sdmcodedBlockPatternLuma <- mkReg(0);
Reg#(Bit#(2)) sdmcodedBlockPatternChroma <- mkReg(0);
Reg#(Bit#(5)) sdmrTotalCoeff <- mkReg(0);
Reg#(Bit#(2)) sdmrTrailingOnes <- mkReg(0);
//derived decoding variables for slice data
Reg#(Bit#(16)) tempreg <- mkReg(0);
Reg#(Bit#(5)) num_ref_idx_l0_active_minus1 <- mkReg(0);
Reg#(Bit#(PicAreaSz)) currMbAddr <- mkReg(0);
Reg#(Bit#(3)) temp3bit0 <- mkReg(0);
Reg#(Bit#(3)) temp3bit1 <- mkReg(0);
Reg#(Bit#(3)) temp3bit2 <- mkReg(0);
Reg#(Bit#(3)) temp3bit3 <- mkReg(0);
Reg#(Bit#(5)) temp5bit <- mkReg(0);
Reg#(Bit#(5)) temp5bit2 <- mkReg(0);
Reg#(Bit#(5)) maxNumCoeff <- mkReg(0);
FIFO#(Bit#(13)) cavlcFIFO <- mkSizedFIFO(16);
Calc_nC calcnc <- mkCalc_nC();
Reg#(Bit#(1)) residualChroma <- mkReg(0);
Reg#(Bit#(5)) totalCoeff <- mkReg(0);
Reg#(Bit#(4)) zerosLeft <- mkReg(0);
//exp-golomb 32-bit version states
Reg#(Bufcount) egnumbits <- mkReg(0);
//extra-buffering states
Reg#(Bit#(32)) extrabuffer <- mkReg(0);
Reg#(Bit#(3)) extrabufcount <- mkReg(0);
Reg#(Bit#(1)) extraendnalflag <- mkReg(0);
Reg#(Bit#(1)) endnalflag <- mkReg(0);
//-----------------------------------------------------------
// Rules
rule startup (state matches Start);
case (infifo.first()) matches
tagged NewUnit :
begin
infifo.deq();
state <= NewUnit;
buffer <= 0;
bufcount <= 0;
extrabuffer <= 0;
extrabufcount <= 0;
extraendnalflag <= 0;
endnalflag <= 0;
end
tagged RbspByte .rdata :
begin
infifo.deq();
end
tagged EndOfFile :
begin
infifo.deq();
outfifo.enq(EndOfFile);
$display( "INFO EntropyDec: EndOfFile reached" );
end
endcase
endrule
rule newunit (state matches NewUnit);
case (infifo.first()) matches
tagged NewUnit : state <= Start;
tagged RbspByte .rdata :
begin
infifo.deq();
nalrefidc <= rdata[6:5];
nalunittype <= rdata[4:0];
case (rdata[4:0])
1 : state <= CodedSlice (0);
5 : state <= CodedSlice (0);
6 : state <= SEI;
7 : state <= SPS (0);
8 : state <= PPS (0);
9 : state <= AUD;
10: state <= EndSequence;
11: state <= EndStream;
12: state <= Filler;
default:
begin
$display( "ERROR EntropyDec: NAL Unit Type = %d", rdata[4:0] );
state <= Start;
end
endcase
$display("ccl2newunit");
$display("ccl2rbspbyte %h", rdata);
outfifo.enq(NewUnit (rdata));
outfifo_ITB.enq(NewUnit (rdata));
end
tagged EndOfFile : state <= Start;
endcase
endrule
rule fillextrabuffer (state != Start
&& state != NewUnit
&& extrabufcount < 4
&& extraendnalflag == 0);
if(infifo.first() matches tagged RbspByte .dbyte)
begin
case ( extrabufcount )
0: extrabuffer <= {dbyte, extrabuffer[23:0]};
1: extrabuffer <= {extrabuffer[31:24],dbyte,extrabuffer[15:0]};
2: extrabuffer <= {extrabuffer[31:16],dbyte,extrabuffer[7:0]};
3: extrabuffer <= {extrabuffer[31:8],dbyte};
default: $display( "ERROR EntropyDec: fillextrabuffer default case_" );
endcase
extrabufcount <= extrabufcount + 1;
infifo.deq();
//$display( "TRACE EntropyDec: fillextrabuffer RbspByte %h %h %h", dbyte, extrabufcount, extrabuffer);
end
else
begin
if(extrabufcount != 0)
extraendnalflag <= 1;
//$display( "TRACE EntropyDec: fillextrabuffer else %h", extrabufcount);
end
endrule
rule fillbuffer (state != Start
&& state != NewUnit
&& bufcount<=truncate(buffersize-32)
&& (extrabufcount == 4 || extraendnalflag == 1)
&& endnalflag == 0);//predicate not sure
Buffer temp = zeroExtend(extrabuffer);
Bufcount temp2 = truncate(buffersize)-bufcount-32;
buffer <= (buffer | (temp << zeroExtend(temp2)));
case ( extrabufcount )
4: bufcount <= bufcount+32;
3: bufcount <= bufcount+24;
2: bufcount <= bufcount+16;
1: bufcount <= bufcount+8;
default: $display( "ERROR EntropyDec: fillbuffer default case" );
endcase
extrabuffer <= 0;
extrabufcount <= 0;
if(infifo.first()==NewUnit || infifo.first()==EndOfFile)
endnalflag <= 1;
//$display( "TRACE EntropyDec: fillbuffer RbspByte %h %h %h %h %h %h %h %h", extrabufcount, bufcount, extrabuffer, temp, temp2, (temp << zeroExtend(temp2)), buffer, (buffer | (temp << zeroExtend(temp2))));
endrule
rule parser (state != Start
&&& state != NewUnit
&&& (bufcount > truncate(buffersize-32) || endnalflag == 1));//predicate not sure
//$display( "TRACE EntropyDec: fillbuffer RbspByte %h %h", bufcount, buffer );
Bufcount numbitsused = 0;
State nextstate = Start;
Int#(16) tempint = 0;
Int#(32) tempint32 = 0;
case ( state ) matches
tagged CodedSlice .step :
begin
case ( step )
0:
begin
$display( "ccl2SHfirst_mb_in_slice %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SHfirst_mb_in_slice (truncate(expgolomb_unsigned(buffer))));
currMbAddr <= truncate(expgolomb_unsigned(buffer));
calcnc.initialize(truncate(expgolomb_unsigned(buffer)));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (1);
end
1:
begin
$display( "ccl2SHslice_type %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SHslice_type (truncate(expgolomb_unsigned(buffer))));
shslice_type <= truncate(expgolomb_unsigned(buffer));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (2);
end
2:
begin
$display( "ccl2SHpic_parameter_set_id %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SHpic_parameter_set_id (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (3);
if(ppspic_parameter_set_id != truncate(expgolomb_unsigned(buffer))) $display( "ERROR EntropyDec: pic_parameter_set_id don't match" );
end
3:
begin
Bit#(16) tttt = buffer[buffersize-1:buffersize-16];
tttt = tttt >> 16 - zeroExtend(spslog2_max_frame_num);
$display( "ccl2SHframe_num %0d", tttt );
outfifo.enq(SHframe_num (tttt));
numbitsused = zeroExtend(spslog2_max_frame_num);
nextstate = CodedSlice (4);
end
4:
begin
if(nalunittype == 5)
begin
$display( "ccl2SHidr_pic_id %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SHidr_pic_id (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
end
nextstate = CodedSlice (5);
end
5:
begin
if(spspic_order_cnt_type == 0)
begin
Bit#(16) tttt = buffer[buffersize-1:buffersize-16];
tttt = tttt >> 16 - zeroExtend(spslog2_max_pic_order_cnt_lsb);
$display( "ccl2SHpic_order_cnt_lsb %0d", tttt );
outfifo.enq(SHpic_order_cnt_lsb (tttt));
numbitsused = zeroExtend(spslog2_max_pic_order_cnt_lsb);
nextstate = CodedSlice (6);
end
else
nextstate = CodedSlice (7);
end
6:
begin
if(ppspic_order_present_flag == 1)
begin
if(egnumbits == 0)
begin
Bufcount tempbufcount = expgolomb_numbits32(buffer);
egnumbits <= tempbufcount;
numbitsused = tempbufcount-1;
nextstate = CodedSlice (6);
end
else
begin
tempint32 = unpack(expgolomb_signed32(buffer,egnumbits));
$display( "ccl2SHdelta_pic_order_cnt_bottom %0d", tempint32 );
outfifo.enq(SHdelta_pic_order_cnt_bottom (truncate(expgolomb_signed32(buffer,egnumbits))));
egnumbits <= 0;
numbitsused = egnumbits;
nextstate = CodedSlice (7);
end
end
else
nextstate = CodedSlice (7);
end
7:
begin
if(spspic_order_cnt_type == 1 && spsdelta_pic_order_always_zero_flag == 0)
begin
if(egnumbits == 0)
begin
Bufcount tempbufcount = expgolomb_numbits32(buffer);
egnumbits <= tempbufcount;
numbitsused = tempbufcount-1;
nextstate = CodedSlice (7);
end
else
begin
tempint32 = unpack(expgolomb_signed32(buffer,egnumbits));
$display( "ccl2SHdelta_pic_order_cnt0 %0d", tempint32 );
outfifo.enq(SHdelta_pic_order_cnt0 (truncate(expgolomb_signed32(buffer,egnumbits))));
egnumbits <= 0;
numbitsused = egnumbits;
nextstate = CodedSlice (8);
end
end
else
nextstate = CodedSlice (9);
end
8:
begin
if(ppspic_order_present_flag == 1)
begin
if(egnumbits == 0)
begin
Bufcount tempbufcount = expgolomb_numbits32(buffer);
egnumbits <= tempbufcount;
numbitsused = tempbufcount-1;
nextstate = CodedSlice (8);
end
else
begin
tempint32 = unpack(expgolomb_signed32(buffer,egnumbits));
$display( "ccl2SHdelta_pic_order_cnt1 %0d", tempint32 );
outfifo.enq(SHdelta_pic_order_cnt1 (truncate(expgolomb_signed32(buffer,egnumbits))));
egnumbits <= 0;
numbitsused = egnumbits;
nextstate = CodedSlice (9);
end
end
else
nextstate = CodedSlice (9);
end
9:
begin
if(shslice_type == 0 || shslice_type == 5)
begin
$display( "ccl2SHnum_ref_idx_active_override_flag %0d", buffer[buffersize-1] );
outfifo.enq(SHnum_ref_idx_active_override_flag (buffer[buffersize-1]));
numbitsused = 1;
if(buffer[buffersize-1] == 1)
nextstate = CodedSlice (10);
else
nextstate = CodedSlice (11);
end
else
nextstate = CodedSlice (11);
end
10:
begin
$display( "ccl2SHnum_ref_idx_l0_active %0d", expgolomb_unsigned(buffer)+1 );
outfifo.enq(SHnum_ref_idx_l0_active (truncate(expgolomb_unsigned(buffer)+1)));
num_ref_idx_l0_active_minus1 <= truncate(expgolomb_unsigned(buffer));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (11);
end
11:
begin
if(shslice_type != 2 && shslice_type != 7)
begin
$display( "ccl2SHRref_pic_list_reordering_flag_l0 %0d", buffer[buffersize-1] );
outfifo.enq(SHRref_pic_list_reordering_flag_l0 (buffer[buffersize-1]));
numbitsused = 1;
if(buffer[buffersize-1] == 1)
nextstate = CodedSlice (12);
else
nextstate = CodedSlice (15);
end
else
nextstate = CodedSlice (15);
end
12:
begin
$display( "ccl2SHRreordering_of_pic_nums_idc %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SHRreordering_of_pic_nums_idc (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
if(expgolomb_unsigned(buffer)==0 || expgolomb_unsigned(buffer)==1)
nextstate = CodedSlice (13);
else if(expgolomb_unsigned(buffer)==2)
nextstate = CodedSlice (14);
else
nextstate = CodedSlice (15);
end
13:
begin
Bit#(17) temp17 = zeroExtend(expgolomb_unsigned(buffer)) + 1;
$display( "ccl2SHRabs_diff_pic_num %0d", temp17 );
outfifo.enq(SHRabs_diff_pic_num (temp17));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (12);
end
14:
begin
$display( "ccl2SHRlong_term_pic_num %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SHRlong_term_pic_num (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (12);
end
15:
begin
if(nalrefidc == 0)
nextstate = CodedSlice (23);
else
begin
if(nalunittype == 5)
begin
$display( "ccl2SHDno_output_of_prior_pics_flag %0d", buffer[buffersize-1] );
outfifo.enq(SHDno_output_of_prior_pics_flag (buffer[buffersize-1]));
numbitsused = 1;
nextstate = CodedSlice (16);
end
else
nextstate = CodedSlice (17);
end
end
16:
begin
$display( "ccl2SHDlong_term_reference_flag %0d", buffer[buffersize-1] );
outfifo.enq(SHDlong_term_reference_flag (buffer[buffersize-1]));
numbitsused = 1;
nextstate = CodedSlice (23);
end
17:
begin
$display( "ccl2SHDadaptive_ref_pic_marking_mode_flag %0d", buffer[buffersize-1] );
outfifo.enq(SHDadaptive_ref_pic_marking_mode_flag (buffer[buffersize-1]));
numbitsused = 1;
if(buffer[buffersize-1] == 1)
nextstate = CodedSlice (18);
else
nextstate = CodedSlice (23);
end
18:
begin
$display( "ccl2SHDmemory_management_control_operation %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SHDmemory_management_control_operation (truncate(expgolomb_unsigned(buffer))));
shdmemory_management_control_operation <= truncate(expgolomb_unsigned(buffer));
numbitsused = expgolomb_numbits(buffer);
if(expgolomb_unsigned(buffer)!=0)
nextstate = CodedSlice (19);
else
nextstate = CodedSlice (23);
end
19:
begin
if(shdmemory_management_control_operation==1 || shdmemory_management_control_operation==3)
begin
Bit#(17) temp17 = zeroExtend(expgolomb_unsigned(buffer)) + 1;
$display( "ccl2SHDdifference_of_pic_nums %0d", temp17 );
outfifo.enq(SHDdifference_of_pic_nums (temp17));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (20);
end
else
nextstate = CodedSlice (20);
end
20:
begin
if(shdmemory_management_control_operation==2)
begin
$display( "ccl2SHDlong_term_pic_num %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SHDlong_term_pic_num (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (21);
end
else
nextstate = CodedSlice (21);
end
21:
begin
if(shdmemory_management_control_operation==3 || shdmemory_management_control_operation==6)
begin
$display( "ccl2SHDlong_term_frame_idx %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SHDlong_term_frame_idx (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (22);
end
else
nextstate = CodedSlice (22);
end
22:
begin
if(shdmemory_management_control_operation==4)
begin
$display( "ccl2SHDmax_long_term_frame_idx_plus1 %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SHDmax_long_term_frame_idx_plus1 (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (18);
end
else
nextstate = CodedSlice (18);
end
23:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SHslice_qp_delta %0d", tempint );
outfifo_ITB.enq(SHslice_qp_delta (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (24);
end
24:
begin
if(ppsdeblocking_filter_control_present_flag==1)
begin
$display( "ccl2SHdisable_deblocking_filter_idc %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SHdisable_deblocking_filter_idc (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
if(expgolomb_unsigned(buffer)!=1)
nextstate = CodedSlice (25);
else
nextstate = CodedSlice (27);
end
else
nextstate = CodedSlice (27);
end
25:
begin
tempint = unpack(expgolomb_signed(buffer) << 1);
$display( "ccl2SHslice_alpha_c0_offset %0d", tempint );
outfifo.enq(SHslice_alpha_c0_offset (truncate(expgolomb_signed(buffer) << 1)));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (26);
end
26:
begin
tempint = unpack(expgolomb_signed(buffer) << 1);
$display( "ccl2SHslice_beta_offset %0d", tempint );
outfifo.enq(SHslice_beta_offset (truncate(expgolomb_signed(buffer) << 1)));
numbitsused = expgolomb_numbits(buffer);
nextstate = CodedSlice (27);
end
27:
begin
nextstate = SliceData (0);
end
default: $display( "ERROR EntropyDec: CodedSlice default step" );
endcase
end
tagged SEI .step :
begin
nextstate = Start;
$display( "INFO EntropyDec: SEI data thrown away" );
end
tagged SPS .step :
begin
case ( step )
0:
begin
Bit#(8) outputdata = buffer[buffersize-1:buffersize-8];
$display( "INFO EntropyDec: profile_idc = %d", outputdata );
outputdata = buffer[buffersize-9:buffersize-16];
$display( "INFO EntropyDec: constraint_set = %b", outputdata );
outputdata = buffer[buffersize-17:buffersize-24];
$display( "INFO EntropyDec: level_idc = %d", outputdata );
numbitsused = 24;
nextstate = SPS (1);
end
1:
begin
$display( "ccl2SPSseq_parameter_set_id %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SPSseq_parameter_set_id (truncate(expgolomb_unsigned(buffer))));
spsseq_parameter_set_id <= truncate(expgolomb_unsigned(buffer));
numbitsused = expgolomb_numbits(buffer);
nextstate = SPS (2);
end
2:
begin
$display( "ccl2SPSlog2_max_frame_num %0d", expgolomb_unsigned(buffer)+4 );
outfifo.enq(SPSlog2_max_frame_num (truncate(expgolomb_unsigned(buffer)+4)));
spslog2_max_frame_num <= truncate(expgolomb_unsigned(buffer)+4);
numbitsused = expgolomb_numbits(buffer);
nextstate = SPS (3);
end
3:
begin
let tttt = expgolomb_unsigned(buffer);
$display( "ccl2SPSpic_order_cnt_type %0d", tttt );
outfifo.enq(SPSpic_order_cnt_type (truncate(tttt)));
spspic_order_cnt_type <= truncate(tttt);
numbitsused = expgolomb_numbits(buffer);
if(tttt == 0)
nextstate = SPS (4);
else if(tttt == 1)
nextstate = SPS (5);
else
nextstate = SPS (10);
end
4:
begin
$display( "ccl2SPSlog2_max_pic_order_cnt_lsb %0d", expgolomb_unsigned(buffer)+4 );
outfifo.enq(SPSlog2_max_pic_order_cnt_lsb (truncate(expgolomb_unsigned(buffer)+4)));
spslog2_max_pic_order_cnt_lsb <= truncate(expgolomb_unsigned(buffer)+4);
numbitsused = expgolomb_numbits(buffer);
nextstate = SPS (10);
end
5:
begin
$display( "ccl2SPSdelta_pic_order_always_zero_flag %0d", buffer[buffersize-1] );
outfifo.enq(SPSdelta_pic_order_always_zero_flag (buffer[buffersize-1]));
spsdelta_pic_order_always_zero_flag <= buffer[buffersize-1];
numbitsused = 1;
nextstate = SPS (6);
end
6:
begin
if(egnumbits == 0)
begin
Bufcount tempbufcount = expgolomb_numbits32(buffer);
egnumbits <= tempbufcount;
numbitsused = tempbufcount-1;
nextstate = SPS (6);
end
else
begin
tempint32 = unpack(expgolomb_signed32(buffer,egnumbits));
$display( "ccl2SPSoffset_for_non_ref_pic %0d", tempint32 );
outfifo.enq(SPSoffset_for_non_ref_pic (truncate(expgolomb_signed32(buffer,egnumbits))));
egnumbits <= 0;
numbitsused = egnumbits;
nextstate = SPS (7);
end
end
7:
begin
if(egnumbits == 0)
begin
Bufcount tempbufcount = expgolomb_numbits32(buffer);
egnumbits <= tempbufcount;
numbitsused = tempbufcount-1;
nextstate = SPS (7);
end
else
begin
tempint32 = unpack(expgolomb_signed32(buffer,egnumbits));
$display( "ccl2SPSoffset_for_top_to_bottom_field %0d", tempint32 );
outfifo.enq(SPSoffset_for_top_to_bottom_field (truncate(expgolomb_signed32(buffer,egnumbits))));
egnumbits <= 0;
numbitsused = egnumbits;
nextstate = SPS (8);
end
end
8:
begin
$display( "ccl2SPSnum_ref_frames_in_pic_order_cnt_cycle %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SPSnum_ref_frames_in_pic_order_cnt_cycle (truncate(expgolomb_unsigned(buffer))));
spsnum_ref_frames_in_pic_order_cnt_cycle <= truncate(expgolomb_unsigned(buffer));
numbitsused = expgolomb_numbits(buffer);
nextstate = SPS (9);
end
9:
begin
if(spsnum_ref_frames_in_pic_order_cnt_cycle == 0)
nextstate = SPS (10);
else
begin
if(egnumbits == 0)
begin
Bufcount tempbufcount = expgolomb_numbits32(buffer);
egnumbits <= tempbufcount;
numbitsused = tempbufcount-1;
nextstate = SPS (9);
end
else
begin
tempint32 = unpack(expgolomb_signed32(buffer,egnumbits));
$display( "ccl2SPSoffset_for_ref_frame %0d", tempint32 );
outfifo.enq(SPSoffset_for_ref_frame (truncate(expgolomb_signed32(buffer,egnumbits))));
egnumbits <= 0;
spsnum_ref_frames_in_pic_order_cnt_cycle <= spsnum_ref_frames_in_pic_order_cnt_cycle - 1;
numbitsused = egnumbits;
nextstate = SPS (9);
end
end
end
10:
begin
$display( "ccl2SPSnum_ref_frames %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SPSnum_ref_frames (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = SPS (11);
end
11:
begin
$display( "ccl2SPSgaps_in_frame_num_allowed_flag %0d", buffer[buffersize-1] );
outfifo.enq(SPSgaps_in_frame_num_allowed_flag (buffer[buffersize-1]));
numbitsused = 1;
nextstate = SPS (12);
end
12:
begin
$display( "ccl2SPSpic_width_in_mbs %0d", expgolomb_unsigned(buffer)+1 );
outfifo.enq(SPSpic_width_in_mbs (truncate(expgolomb_unsigned(buffer)+1)));
calcnc.initialize_picWidth(truncate(expgolomb_unsigned(buffer)+1));
numbitsused = expgolomb_numbits(buffer);
nextstate = SPS (13);
end
13:
begin
$display( "ccl2SPSpic_height_in_map_units %0d", expgolomb_unsigned(buffer)+1 );
outfifo.enq(SPSpic_height_in_map_units (truncate(expgolomb_unsigned(buffer)+1)));
numbitsused = expgolomb_numbits(buffer);
nextstate = SPS (14);
end
14:
begin
//SPSframe_mbs_only_flag = 1 for baseline
numbitsused = 1;
nextstate = SPS (15);
end
15:
begin
$display( "ccl2SPSdirect_8x8_inference_flag %0d", buffer[buffersize-1] );
outfifo.enq(SPSdirect_8x8_inference_flag (buffer[buffersize-1]));
numbitsused = 1;
nextstate = SPS (16);
end
16:
begin
$display( "ccl2SPSframe_cropping_flag %0d", buffer[buffersize-1] );
outfifo.enq(SPSframe_cropping_flag (buffer[buffersize-1]));
numbitsused = 1;
if(buffer[buffersize-1] == 1)
nextstate = SPS (17);
else
nextstate = SPS (21);
end
17:
begin
$display( "ccl2SPSframe_crop_left_offset %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SPSframe_crop_left_offset (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = SPS (18);
end
18:
begin
$display( "ccl2SPSframe_crop_right_offset %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SPSframe_crop_right_offset (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = SPS (19);
end
19:
begin
$display( "ccl2SPSframe_crop_top_offset %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SPSframe_crop_top_offset (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = SPS (20);
end
20:
begin
$display( "ccl2SPSframe_crop_bottom_offset %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SPSframe_crop_bottom_offset (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = SPS (21);
end
21:
begin
nextstate = Start;
$display( "INFO EntropyDec:VUI data thrown away" );
end
default: $display( "ERROR EntropyDec: SPS default step" );
endcase
end
tagged PPS .step :
begin
case ( step )
0:
begin
ppspic_parameter_set_id <= truncate(expgolomb_unsigned(buffer));
$display( "ccl2PPSpic_parameter_set_id %0d", expgolomb_unsigned(buffer) );
outfifo.enq(PPSpic_parameter_set_id (truncate(expgolomb_unsigned(buffer))));
outfifo_ITB.enq(PPSpic_parameter_set_id (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = PPS (1);
end
1:
begin
$display( "ccl2PPSseq_parameter_set_id %0d", expgolomb_unsigned(buffer) );
outfifo.enq(PPSseq_parameter_set_id (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = PPS (2);
if(spsseq_parameter_set_id != truncate(expgolomb_unsigned(buffer)))
$display( "ERROR EntropyDec: seq_parameter_set_id don't match" );
end
2:
begin
//PPSentropy_coding_mode_flag = 0 for baseline
numbitsused = 1;
nextstate = PPS (3);
end
3:
begin
ppspic_order_present_flag <= buffer[buffersize-1];
$display( "ccl2PPSpic_order_present_flag %0d", buffer[buffersize-1] );
outfifo.enq(PPSpic_order_present_flag (buffer[buffersize-1]));
numbitsused = 1;
nextstate = PPS (4);
end
4:
begin
numbitsused = expgolomb_numbits(buffer);
nextstate = PPS (5);
if(expgolomb_unsigned(buffer)+1 != 1)
$display( "ERROR EntropyDec: PPSnum_slice_groups not equal to 1" );//=1 for main
end
5:
begin
$display( "ccl2PPSnum_ref_idx_l0_active %0d", expgolomb_unsigned(buffer)+1 );
outfifo.enq(PPSnum_ref_idx_l0_active (truncate(expgolomb_unsigned(buffer)+1)));
num_ref_idx_l0_active_minus1 <= truncate(expgolomb_unsigned(buffer));
numbitsused = expgolomb_numbits(buffer);
nextstate = PPS (6);
end
6:
begin
$display( "ccl2PPSnum_ref_idx_l1_active %0d", expgolomb_unsigned(buffer)+1 );
outfifo.enq(PPSnum_ref_idx_l1_active (truncate(expgolomb_unsigned(buffer)+1)));
numbitsused = expgolomb_numbits(buffer);
nextstate = PPS (7);
end
7:
begin
//PPSweighted_pred_flag = 0 for baseline; PPSweighted_bipred_idc = 0 for baseline
numbitsused = 3;
nextstate = PPS (8);
end
8:
begin
$display( "ccl2PPSpic_init_qp %0d", expgolomb_signed(buffer)+26 );
outfifo_ITB.enq(PPSpic_init_qp (truncate(expgolomb_signed(buffer)+26)));
numbitsused = expgolomb_numbits(buffer);
nextstate = PPS (9);
end
9:
begin
$display( "ccl2PPSpic_init_qs %0d", expgolomb_signed(buffer)+26 );
outfifo_ITB.enq(PPSpic_init_qs (truncate(expgolomb_signed(buffer)+26)));
numbitsused = expgolomb_numbits(buffer);
nextstate = PPS (10);
end
10:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2PPSchroma_qp_index_offset %0d", tempint );
outfifo_ITB.enq(PPSchroma_qp_index_offset (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = PPS (11);
end
11:
begin
ppsdeblocking_filter_control_present_flag <= buffer[buffersize-1];
$display( "ccl2PPSdeblocking_filter_control_present_flag %0d", buffer[buffersize-1] );
outfifo.enq(PPSdeblocking_filter_control_present_flag (buffer[buffersize-1]));
numbitsused = 1;
nextstate = PPS (12);
end
12:
begin
$display( "ccl2PPSconstrained_intra_pred_flag %0d", buffer[buffersize-1] );
outfifo.enq(PPSconstrained_intra_pred_flag (buffer[buffersize-1]));
numbitsused = 1;
nextstate = PPS (13);
end
13:
begin
//PPSredundant_pic_cnt_present_flag = 0 for main
numbitsused = 1;
nextstate = PPS (14);
if(buffer[buffersize-1] != 0)
$display( "ERROR EntropyDec: PPSredundant_pic_cnt_present_flag not equal to 0" );//=0 for main
end
14:
begin
nextstate = Start;
end
default: $display( "ERROR EntropyDec: PPS default step" );
endcase
end
tagged AUD .step :
begin
outfifo.enq(AUDPrimaryPicType (buffer[buffersize-1:buffersize-3]));
numbitsused = 3;
nextstate = Start;
end
tagged EndSequence :
begin
outfifo.enq(EndOfSequence);
nextstate = Start;
end
tagged EndStream :
begin
outfifo.enq(EndOfStream);
nextstate = Start;
end
tagged Filler :
begin
nextstate = Start;
end
tagged SliceData .step :
begin
case ( step )
0:
begin
if( shslice_type!=2 && shslice_type!=7 )
begin
$display( "ccl2SDmb_skip_run %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDmb_skip_run (truncate(expgolomb_unsigned(buffer))));
tempreg <= truncate(expgolomb_unsigned(buffer));
calcnc.nNupdate_pskip( truncate(expgolomb_unsigned(buffer)) );
numbitsused = expgolomb_numbits(buffer);
nextstate = SliceData (1);
end
else
nextstate = SliceData (2);
end
1:
begin
if( tempreg>0 )
begin
currMbAddr <= currMbAddr+1;//only because input assumed to comform to both baseline and main
tempreg <= tempreg-1;
nextstate = SliceData (1);
end
else
begin
////$display( "ccl2SDcurrMbAddr %0d", currMbAddr );
////outfifo.enq(SDcurrMbAddr currMbAddr);
nextstate = SliceData (2);
end
end
2:
begin
if( bufcount>8 || buffer[buffersize-1]!=1 || (buffer<<1)!=0 )
begin
calcnc.loadMb(currMbAddr);
nextstate = MacroblockLayer (0);
end
else
nextstate = SliceData (3);
end
3:
begin
currMbAddr <= currMbAddr+1;//only because input assumed to comform to both baseline and main
if( bufcount>8 || buffer[buffersize-1]!=1 || (buffer<<1)!=0 )
nextstate = SliceData (0);
else
nextstate = Start;
end
default: $display( "ERROR EntropyDec: SliceData default step" );
endcase
end
tagged MacroblockLayer .step : //return to SliceData 3
begin
case ( step )
0:
begin
$display( "ccl2SDMmb_type %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMmbtype (mbtype_convert(truncate(expgolomb_unsigned(buffer)), shslice_type)) );
outfifo_ITB.enq(SDMmbtype (mbtype_convert(truncate(expgolomb_unsigned(buffer)), shslice_type)) );
sdmmbtype <= mbtype_convert(truncate(expgolomb_unsigned(buffer)), shslice_type);
numbitsused = expgolomb_numbits(buffer);
if(mbtype_convert(truncate(expgolomb_unsigned(buffer)), shslice_type) == I_PCM)
begin
calcnc.nNupdate_ipcm();
nextstate = MacroblockLayer (1);
end
else
nextstate = MacroblockLayer (4);
end
1:
begin
tempreg <= 256;
numbitsused = zeroExtend(bufcount[2:0]);
nextstate = MacroblockLayer (2);
end
2:
begin
if( tempreg>0 )
begin
Bit#(8) outputdata = buffer[buffersize-1:buffersize-8];
$display( "ccl2SDMpcm_sample_luma %0d", outputdata );
outfifo.enq(SDMpcm_sample_luma (outputdata));
tempreg <= tempreg-1;
numbitsused = 8;
nextstate = MacroblockLayer (2);
end
else
begin
tempreg <= 128;
nextstate = MacroblockLayer (3);
end
end
3:
begin
if( tempreg>0 )
begin
Bit#(8) outputdata = buffer[buffersize-1:buffersize-8];
$display( "ccl2SDMpcm_sample_chroma %0d", outputdata );
outfifo.enq(SDMpcm_sample_chroma (outputdata));
tempreg <= tempreg-1;
numbitsused = 8;
nextstate = MacroblockLayer (3);
end
else
nextstate = SliceData (3);
end
4:
begin
if(sdmmbtype != I_NxN
&&& mbPartPredMode(sdmmbtype,0) != Intra_16x16
&&& numMbPart(sdmmbtype) == 4)
nextstate = SubMbPrediction (0);
else
nextstate = MbPrediction (0);
end
5:
begin
if(mbPartPredMode(sdmmbtype,0) != Intra_16x16)
begin
$display( "ccl2SDMcoded_block_pattern %0d", expgolomb_coded_block_pattern(buffer,sdmmbtype) );
////outfifo.enq(SDMcoded_block_pattern expgolomb_coded_block_pattern(buffer,sdmmbtype));
sdmcodedBlockPatternLuma <= expgolomb_coded_block_pattern(buffer,sdmmbtype)[3:0];
sdmcodedBlockPatternChroma <= expgolomb_coded_block_pattern(buffer,sdmmbtype)[5:4];
numbitsused = expgolomb_numbits(buffer);
end
else
begin
if(sdmmbtype matches tagged I_16x16 {intra16x16PredMode:.tempv1, codedBlockPatternChroma:.tempv2, codedBlockPatternLuma:.tempv3})
begin
sdmcodedBlockPatternLuma <= {tempv3,tempv3,tempv3,tempv3};
sdmcodedBlockPatternChroma <= tempv2;
end
else
$display( "ERROR EntropyDec: MacroblockLayer 5 sdmmbtype not I_16x16" );
end
nextstate = MacroblockLayer (6);
end
6:
begin
if(sdmcodedBlockPatternLuma > 0
|| sdmcodedBlockPatternChroma > 0
|| mbPartPredMode(sdmmbtype,0) == Intra_16x16)
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SDMmb_qp_delta %0d", tempint );
outfifo_ITB.enq(SDMmb_qp_delta (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
end
residualChroma <= 0;
temp5bit <= 0;
maxNumCoeff <= 16;
nextstate = ResidualBlock (0);
end
default: $display( "ERROR EntropyDec: MacroblockLayer default step" );
endcase
end
tagged MbPrediction .step : //return to MacroblockLayer 5
begin
case ( step )
0:
begin
if(mbPartPredMode(sdmmbtype,0) == Intra_16x16)
begin
$display( "ccl2SDMMintra_chroma_pred_mode %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMMintra_chroma_pred_mode (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = MacroblockLayer (5);
end
else if(mbPartPredMode(sdmmbtype,0) == Intra_4x4)
begin
temp5bit <= 16;
nextstate = MbPrediction (1);
end
else if(num_ref_idx_l0_active_minus1 > 0)
begin
temp3bit0 <= numMbPart(sdmmbtype);
nextstate = MbPrediction (2);
end
else
begin
temp3bit0 <= numMbPart(sdmmbtype);
nextstate = MbPrediction (3);
end
end
1:
begin
if(temp5bit == 0)
begin
$display( "ccl2SDMMintra_chroma_pred_mode %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMMintra_chroma_pred_mode (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = MacroblockLayer (5);
end
else
begin
////$display( "ccl2SDMMprev_intra4x4_pred_mode_flag %0d", buffer[buffersize-1] );
if(buffer[buffersize-1] == 0)
begin
Bit#(4) tttt = buffer[buffersize-1:buffersize-4];
$display( "ccl2SDMMrem_intra4x4_pred_mode %0d", tttt );
outfifo.enq(SDMMrem_intra4x4_pred_mode (tttt));
numbitsused = 4;
end
else
begin
outfifo.enq(SDMMrem_intra4x4_pred_mode (4'b1000));
numbitsused = 1;
end
temp5bit <= temp5bit-1;
nextstate = MbPrediction (1);
end
end
2:
begin
if(num_ref_idx_l0_active_minus1 == 1)
begin
$display( "ccl2SDMMref_idx_l0 %0d", 1-buffer[buffersize-1] );
outfifo.enq(SDMMref_idx_l0 (zeroExtend(1-buffer[buffersize-1])));
numbitsused = 1;
end
else
begin
$display( "ccl2SDMMref_idx_l0 %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMMref_idx_l0 (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
end
if(temp3bit0 == 1)
begin
temp3bit0 <= numMbPart(sdmmbtype);
nextstate = MbPrediction (3);
end
else
begin
temp3bit0 <= temp3bit0-1;
nextstate = MbPrediction (2);
end
end
3:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SDMMmvd_l0 %0d", tempint );
outfifo.enq(SDMMmvd_l0 (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = MbPrediction (4);
end
4:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SDMMmvd_l0 %0d", tempint );
outfifo.enq(SDMMmvd_l0 (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
temp3bit0 <= temp3bit0-1;
if(temp3bit0 == 1)
nextstate = MacroblockLayer (5);
else
nextstate = MbPrediction (3);
end
default: $display( "ERROR EntropyDec: MbPrediction default step" );
endcase
end
tagged SubMbPrediction .step : //return to MacroblockLayer 5
begin
case ( step )
0:
begin
$display( "ccl2SDMSsub_mb_type %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMSsub_mb_type (truncate(expgolomb_unsigned(buffer))));
temp3bit0 <= numSubMbPart(truncate(expgolomb_unsigned(buffer)));
numbitsused = expgolomb_numbits(buffer);
nextstate = SubMbPrediction (1);
end
1:
begin
$display( "ccl2SDMSsub_mb_type %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMSsub_mb_type (truncate(expgolomb_unsigned(buffer))));
temp3bit1 <= numSubMbPart(truncate(expgolomb_unsigned(buffer)));
numbitsused = expgolomb_numbits(buffer);
nextstate = SubMbPrediction (2);
end
2:
begin
$display( "ccl2SDMSsub_mb_type %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMSsub_mb_type (truncate(expgolomb_unsigned(buffer))));
temp3bit2 <= numSubMbPart(truncate(expgolomb_unsigned(buffer)));
numbitsused = expgolomb_numbits(buffer);
nextstate = SubMbPrediction (3);
end
3:
begin
$display( "ccl2SDMSsub_mb_type %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMSsub_mb_type (truncate(expgolomb_unsigned(buffer))));
temp3bit3 <= numSubMbPart(truncate(expgolomb_unsigned(buffer)));
numbitsused = expgolomb_numbits(buffer);
if(num_ref_idx_l0_active_minus1 > 0
&& sdmmbtype != P_8x8ref0)
nextstate = SubMbPrediction (4);
else
nextstate = SubMbPrediction (8);
end
4:
begin
if(num_ref_idx_l0_active_minus1 == 1)
begin
$display( "ccl2SDMSref_idx_l0 %0d", 1-buffer[buffersize-1] );
outfifo.enq(SDMSref_idx_l0 (zeroExtend(1-buffer[buffersize-1])));
numbitsused = 1;
end
else
begin
$display( "ccl2SDMSref_idx_l0 %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMSref_idx_l0 (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
end
nextstate = SubMbPrediction (5);
end
5:
begin
if(num_ref_idx_l0_active_minus1 == 1)
begin
$display( "ccl2SDMSref_idx_l0 %0d", 1-buffer[buffersize-1] );
outfifo.enq(SDMSref_idx_l0 (zeroExtend(1-buffer[buffersize-1])));
numbitsused = 1;
end
else
begin
$display( "ccl2SDMSref_idx_l0 %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMSref_idx_l0 (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
end
nextstate = SubMbPrediction (6);
end
6:
begin
if(num_ref_idx_l0_active_minus1 == 1)
begin
$display( "ccl2SDMSref_idx_l0 %0d", 1-buffer[buffersize-1] );
outfifo.enq(SDMSref_idx_l0 (zeroExtend(1-buffer[buffersize-1])));
numbitsused = 1;
end
else
begin
$display( "ccl2SDMSref_idx_l0 %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMSref_idx_l0 (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
end
nextstate = SubMbPrediction (7);
end
7:
begin
if(num_ref_idx_l0_active_minus1 == 1)
begin
$display( "ccl2SDMSref_idx_l0 %0d", 1-buffer[buffersize-1] );
outfifo.enq(SDMSref_idx_l0 (zeroExtend(1-buffer[buffersize-1])));
numbitsused = 1;
end
else
begin
$display( "ccl2SDMSref_idx_l0 %0d", expgolomb_unsigned(buffer) );
outfifo.enq(SDMSref_idx_l0 (truncate(expgolomb_unsigned(buffer))));
numbitsused = expgolomb_numbits(buffer);
end
nextstate = SubMbPrediction (8);
end
8:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SDMSmvd_l0 %0d", tempint );
outfifo.enq(SDMSmvd_l0 (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = SubMbPrediction (9);
end
9:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SDMSmvd_l0 %0d", tempint );
outfifo.enq(SDMSmvd_l0 (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
temp3bit0 <= temp3bit0-1;
if(temp3bit0 == 1)
nextstate = SubMbPrediction (10);
else
nextstate = SubMbPrediction (8);
end
10:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SDMSmvd_l0 %0d", tempint );
outfifo.enq(SDMSmvd_l0 (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = SubMbPrediction (11);
end
11:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SDMSmvd_l0 %0d", tempint );
outfifo.enq(SDMSmvd_l0 (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
temp3bit1 <= temp3bit1-1;
if(temp3bit1 == 1)
nextstate = SubMbPrediction (12);
else
nextstate = SubMbPrediction (10);
end
12:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SDMSmvd_l0 %0d", tempint );
outfifo.enq(SDMSmvd_l0 (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = SubMbPrediction (13);
end
13:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SDMSmvd_l0 %0d", tempint );
outfifo.enq(SDMSmvd_l0 (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
temp3bit2 <= temp3bit2-1;
if(temp3bit2 == 1)
nextstate = SubMbPrediction (14);
else
nextstate = SubMbPrediction (12);
end
14:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SDMSmvd_l0 %0d", tempint );
outfifo.enq(SDMSmvd_l0 (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
nextstate = SubMbPrediction (15);
end
15:
begin
tempint = unpack(expgolomb_signed(buffer));
$display( "ccl2SDMSmvd_l0 %0d", tempint );
outfifo.enq(SDMSmvd_l0 (truncate(expgolomb_signed(buffer))));
numbitsused = expgolomb_numbits(buffer);
temp3bit3 <= temp3bit3-1;
if(temp3bit3 == 1)
nextstate = MacroblockLayer (5);
else
nextstate = SubMbPrediction (14);
end
default: $display( "ERROR EntropyDec: SubMbPrediction default step" );
endcase
end
tagged ResidualBlock .step : //if(residualChroma==0) return to Residual 1; else if(maxNumCoeff==4) return to Residual 3; else return to Residual 5
begin//don't modify maxNumCoeff, residualChroma, and increment temp5bit on return
case ( step )
0:
begin
cavlcFIFO.clear();
if(maxNumCoeff != 4)
begin
if(residualChroma == 0)
tempreg <= zeroExtend(calcnc.nCcalc_luma(truncate(temp5bit)));
else
tempreg <= zeroExtend(calcnc.nCcalc_chroma(truncate(temp5bit)));
end
else
tempreg <= zeroExtend(6'b111111);
if(mbPartPredMode(sdmmbtype,0)==Intra_16x16 && maxNumCoeff==16)
nextstate = ResidualBlock (1);
else if(residualChroma==0 && (sdmcodedBlockPatternLuma & (1 << zeroExtend(temp5bit[3:2])))==0)
begin
calcnc.nNupdate_luma(truncate(temp5bit),0);
outfifo_ITB.enq(SDMRcoeffLevelZeros (maxNumCoeff));
nextstate = ResidualBlock (5);
end
else if(residualChroma==1 && maxNumCoeff==4 && (sdmcodedBlockPatternChroma & 3)==0)
begin
outfifo_ITB.enq(SDMRcoeffLevelZeros (4));
nextstate = ResidualBlock (5);
end
else if(residualChroma==1 && maxNumCoeff!=4 && (sdmcodedBlockPatternChroma & 2)==0)
begin
calcnc.nNupdate_chroma(truncate(temp5bit),0);
outfifo_ITB.enq(SDMRcoeffLevelZeros (15));
nextstate = ResidualBlock (5);
end
else
nextstate = ResidualBlock (1);
//$display( "TRACE EntropyDec: ResidualBlock 0 temp5bit = %0d", temp5bit);
end
1:
begin
Bit#(2) trailingOnesTemp = 0;
Bit#(5) totalCoeffTemp = 0;
{trailingOnesTemp,totalCoeffTemp,numbitsused} = cavlc_coeff_token( buffer, truncate(tempreg) );
temp3bit0 <= zeroExtend(trailingOnesTemp);//trailingOnes
totalCoeff <= totalCoeffTemp;
if(residualChroma == 0 && !(mbPartPredMode(sdmmbtype,0)==Intra_16x16 && maxNumCoeff==16))
calcnc.nNupdate_luma(truncate(temp5bit),totalCoeffTemp);
else if(residualChroma == 1 && maxNumCoeff != 4)
calcnc.nNupdate_chroma(truncate(temp5bit),totalCoeffTemp);
temp5bit2 <= 0;//i
tempreg <= 0;//levelCode temp
if(totalCoeffTemp > 10 && trailingOnesTemp < 3)
temp3bit1 <= 1;//suffixLength
else
temp3bit1 <= 0;//suffixLength
nextstate = ResidualBlock (2);
//$display( "TRACE EntropyDec: ResidualBlock 1 nC = %0d", tempreg);
$display( "ccl2SDMRtotal_coeff %0d", totalCoeffTemp );
$display( "ccl2SDMRtrailing_ones %0d", trailingOnesTemp );
end
2:
begin
if( totalCoeff != 0 )
begin
if(temp5bit2 < zeroExtend(temp3bit0))
begin
if(buffer[buffersize-1] == 1)
cavlcFIFO.enq(-1);
else
cavlcFIFO.enq(1);
numbitsused = 1;
end
else
begin
Bit#(32) buffertempshow = buffer[buffersize-1:buffersize-32];
Bit#(3) suffixLength = temp3bit1;
Bit#(4) levelSuffixSize = zeroExtend(suffixLength);
Bit#(4) level_prefix = cavlc_level_prefix( buffer );
Bit#(5) temp_level_prefix = zeroExtend(level_prefix);
Bit#(28) tempbuffer = buffer[buffersize-1:buffersize-28] << zeroExtend(temp_level_prefix+1);
Bit#(14) levelCode = zeroExtend(level_prefix) << zeroExtend(suffixLength);
if(level_prefix == 14 && suffixLength == 0)
levelSuffixSize = 4;
else if(level_prefix == 15)
levelSuffixSize = 12;
levelCode = levelCode + zeroExtend(tempbuffer[27:16] >> (12-zeroExtend(levelSuffixSize)));//level_suffix
if(level_prefix == 15 && suffixLength == 0)
levelCode = levelCode + 15;
if(temp5bit2 == zeroExtend(temp3bit0) && temp3bit0 < 3)
levelCode = levelCode + 2;
if(suffixLength == 0)
suffixLength = 1;
if( suffixLength < 6 && ((levelCode+2) >> 1) > (3 << zeroExtend(suffixLength-1)) )
suffixLength = suffixLength+1;
if(levelCode[0] == 0)
cavlcFIFO.enq(truncate((levelCode+2) >> 1));
else
cavlcFIFO.enq(truncate((~levelCode) >> 1));
if(levelCode[0] == 0)//////////////////////////////////////////////////
begin
tempint = signExtend(unpack((levelCode+2) >> 1));
//$display( "TRACE EntropyDec: temp level %0d", tempint );
end
else
begin
Bit#(13) tempinttemp = truncate((~levelCode) >> 1);
tempint = signExtend(unpack(tempinttemp));
//$display( "TRACE EntropyDec: temp level %0d", tempint );
end///////////////////////////////////////////////////////////////////////
temp3bit1 <= suffixLength;
numbitsused = zeroExtend(level_prefix)+1+zeroExtend(levelSuffixSize);
end
end
if( totalCoeff==0 || temp5bit2+1==totalCoeff )
begin
temp5bit2 <= 0;
zerosLeft <= 0;
if(totalCoeff < maxNumCoeff)
nextstate = ResidualBlock (3);
else
nextstate = ResidualBlock (5);
end
else
begin
temp5bit2 <= temp5bit2 + 1;
nextstate = ResidualBlock (2);
end
end
3:
begin
Bit#(4) tempZerosLeft;
if(totalCoeff > 0)
begin
{tempZerosLeft,numbitsused} = cavlc_total_zeros( buffer, truncate(totalCoeff), maxNumCoeff);
$display( "ccl2SDMRtotal_zeros %0d", tempZerosLeft );//////////////////////////////////////
end
else
tempZerosLeft = 0;
zerosLeft <= tempZerosLeft;
if(maxNumCoeff - totalCoeff - zeroExtend(tempZerosLeft) > 0)
begin
$display( "ccl2SDMRcoeffLevelZeros %0d", maxNumCoeff - totalCoeff - zeroExtend(tempZerosLeft) );
outfifo_ITB.enq(SDMRcoeffLevelZeros (maxNumCoeff - totalCoeff - zeroExtend(tempZerosLeft)));
end
nextstate = ResidualBlock (5);
end
5:
begin
if( totalCoeff > 0 )
begin
tempint = signExtend(unpack(cavlcFIFO.first()));
$display( "ccl2SDMRcoeffLevel %0d", tempint );
if( zerosLeft > 0 )
begin
Bit#(4) run_before = 0;
if( totalCoeff > 1 )
{run_before,numbitsused} = cavlc_run_before( buffer, zerosLeft);
else
run_before = zerosLeft;
zerosLeft <= zerosLeft - run_before;
outfifo_ITB.enq(SDMRcoeffLevelPlusZeros {level:cavlcFIFO.first(),zeros:zeroExtend(run_before)});
if( run_before > 0 )
$display( "ccl2SDMRcoeffLevelZeros %0d", run_before );
end
else
outfifo_ITB.enq(SDMRcoeffLevelPlusZeros {level:cavlcFIFO.first(),zeros:0});
cavlcFIFO.deq();
totalCoeff <= totalCoeff-1;
end
if( totalCoeff <= 1 )
begin
if(residualChroma==0)
begin
nextstate = ResidualBlock (0);
if(mbPartPredMode(sdmmbtype,0)==Intra_16x16 && maxNumCoeff==16)
maxNumCoeff <= 15;
else if(temp5bit==15)
begin
temp5bit <= 0;
maxNumCoeff <= 4;
residualChroma <= 1;
end
else
temp5bit <= temp5bit+1;
end
else if(maxNumCoeff==4)
begin
nextstate = ResidualBlock (0);
if(temp5bit==1)
begin
temp5bit <= 0;
maxNumCoeff <= 15;
end
else
temp5bit <= temp5bit+1;
end
else
begin
if(temp5bit==7)
begin
temp5bit <= 0;
nextstate = SliceData (3);
end
else
begin
nextstate = ResidualBlock (0);
temp5bit <= temp5bit+1;
end
end
end
else
nextstate = ResidualBlock (5);
end
default: $display( "ERROR EntropyDec: ResidualBlock default step" );
endcase
end
endcase
if(numbitsused+1 > bufcount)
begin
$display( "ERROR EntropyDec: not enough bits in buffer" );
nextstate = Start;
end
buffer <= buffer << zeroExtend(numbitsused);
bufcount <= bufcount-numbitsused;
state <= nextstate;
endrule
interface Put ioin = fifoToPut(infifo);
interface Get ioout = fifoToGet(outfifo);
interface Get ioout_InverseTrans = fifoToGet(outfifo_ITB);
interface mem_client = calcnc.mem_client;
endmodule
endpackage
Go to most recent revision | Compare with Previous | Blame | View Log