www.pudn.com > H264verilogcore.rar > Inter_pred_pipeline.v, change:2008-05-24,size:34093b


//--------------------------------------------------------------------------------------------------
// Design    : nova
// Author(s) : Ke Xu
// Email	   : eexuke@yahoo.com
// File      : Inter_pred_pipeline.v
// Generated : Oct 4, 2005
// Copyright (C) 2008 Ke Xu                
//-------------------------------------------------------------------------------------------------
// Description 
// Inter prediction pipeline
//-------------------------------------------------------------------------------------------------
// Revise log 
// 1.July 23,2006
// Change the ext_frame_RAM from async read to sync read.Therefore,blk4x4_inter_preload_counter has to +1 for all the cases
//-------------------------------------------------------------------------------------------------

// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "nova_defines.v"

module Inter_pred_pipeline (clk,reset_n,
	mb_num_h,mb_num_v,trigger_blk4x4_inter_pred,blk4x4_rec_counter,mb_type_general_bit3,
	mv_is16x16,mv_below8x8,
	mvx_CurrMb0,mvx_CurrMb1,mvx_CurrMb2,mvx_CurrMb3,
	mvy_CurrMb0,mvy_CurrMb1,mvy_CurrMb2,mvy_CurrMb3,
	Inter_pix_copy0,Inter_pix_copy1,Inter_pix_copy2,Inter_pix_copy3,
	LPE0_out,LPE1_out,LPE2_out,LPE3_out,
	CPE0_out,CPE1_out,CPE2_out,CPE3_out,
	
	mv_below8x8_curr,blk4x4_inter_preload_counter,blk4x4_inter_calculate_counter,Inter_chroma2x2_counter,
	end_of_one_blk4x4_inter,IsInterLuma,IsInterChroma,Is_InterChromaCopy,
	xInt_addr_unclip,xInt_org_unclip_1to0,pos_FracL,xFracC,yFracC,
	Inter_pred_out0,Inter_pred_out1,Inter_pred_out2,Inter_pred_out3,Inter_blk4x4_pred_output_valid,
	ref_frame_RAM_rd,ref_frame_RAM_rd_addr);
	input clk;
	input reset_n;
	input [3:0] mb_num_h,mb_num_v;
	input trigger_blk4x4_inter_pred;
	input [4:0] blk4x4_rec_counter;
	input mb_type_general_bit3;
	input mv_is16x16;
	input [3:0] mv_below8x8;
	input [31:0] mvx_CurrMb0,mvx_CurrMb1,mvx_CurrMb2,mvx_CurrMb3;
	input [31:0] mvy_CurrMb0,mvy_CurrMb1,mvy_CurrMb2,mvy_CurrMb3;
	input [7:0] Inter_pix_copy0,Inter_pix_copy1,Inter_pix_copy2,Inter_pix_copy3;
	input [7:0] LPE0_out,LPE1_out,LPE2_out,LPE3_out;
	input [7:0] CPE0_out,CPE1_out,CPE2_out,CPE3_out;
	
	output mv_below8x8_curr;
	output [5:0] blk4x4_inter_preload_counter;
	output [3:0] blk4x4_inter_calculate_counter;
	output [1:0] Inter_chroma2x2_counter;
	output end_of_one_blk4x4_inter;
	output IsInterLuma,IsInterChroma;
	output Is_InterChromaCopy;
	output [8:0] xInt_addr_unclip;
	output [1:0] xInt_org_unclip_1to0;
	output [3:0] pos_FracL;
	output [2:0] xFracC,yFracC;
	output [7:0] Inter_pred_out0,Inter_pred_out1,Inter_pred_out2,Inter_pred_out3;
	output [1:0] Inter_blk4x4_pred_output_valid;	//2'b01:luma output valid	2'b10:chroma output valid
	output ref_frame_RAM_rd;
	output [13:0] ref_frame_RAM_rd_addr;
	
	reg [5:0] blk4x4_inter_preload_counter;
	reg [3:0] blk4x4_inter_calculate_counter;
	reg mv_below8x8_curr;
	reg [7:0] Inter_pred_out0,Inter_pred_out1,Inter_pred_out2,Inter_pred_out3;
	reg [1:0] Inter_blk4x4_pred_output_valid;
	wire ref_frame_RAM_rd; 
	wire IsInterLuma;
	wire IsInterChroma;
	wire [1:0] xFracL;
	wire [1:0] yFracL;
	wire [2:0] xFracC;
	wire [2:0] yFracC;
	wire [13:0] ref_frame_RAM_rd_addr;
		
	assign IsInterLuma   = (!mb_type_general_bit3 && blk4x4_rec_counter < 16)? 1'b1:1'b0;
	assign IsInterChroma = (!mb_type_general_bit3 && blk4x4_rec_counter > 15)? 1'b1:1'b0;
	//-------------------------------------------------------------------------
	//mv_below8x8_curr for each 2x2 Inter Chroma prediction
	//-------------------------------------------------------------------------	
	always @ (IsInterLuma or IsInterChroma or blk4x4_rec_counter[3:0] or mv_below8x8)
		if (IsInterLuma)
			case (blk4x4_rec_counter[3:2])
				2'b00:mv_below8x8_curr <= mv_below8x8[0];
				2'b01:mv_below8x8_curr <= mv_below8x8[1];
				2'b10:mv_below8x8_curr <= mv_below8x8[2];
				2'b11:mv_below8x8_curr <= mv_below8x8[3];
			endcase
		else if (IsInterChroma)
			case (blk4x4_rec_counter[1:0])
				2'b00:mv_below8x8_curr <= mv_below8x8[0];
				2'b01:mv_below8x8_curr <= mv_below8x8[1];
				2'b10:mv_below8x8_curr <= mv_below8x8[2];
				2'b11:mv_below8x8_curr <= mv_below8x8[3];
			endcase
		else
			mv_below8x8_curr <= 0;
	//----------------------------------------------------------------------------------------
	//Inter_chroma2x2_counter to guide the prediction of 2x2 chroma blocks
	//2'b11 -> 2'b10 -> 2'b01 -> 2'b00
	//----------------------------------------------------------------------------------------
	reg [1:0] Inter_chroma2x2_counter;		
	always @ (posedge clk)
		if (reset_n == 1'b0)
			Inter_chroma2x2_counter <= 0;
		//mv_below8x8_curr == 1'b1 includes the condition that "blk4x4_rec_counter > 15"
		else if (IsInterChroma && trigger_blk4x4_inter_pred && mv_below8x8_curr)
			Inter_chroma2x2_counter <= 2'b11;
		else if	(blk4x4_inter_calculate_counter == 4'd1 && Inter_chroma2x2_counter != 0)
			Inter_chroma2x2_counter <= Inter_chroma2x2_counter - 1;
	
	//----------------------------------------------------------------------------------------
	//trigger_blk2x2_inter_pred:only for chroma 2x2 decoding
	//We introduce this additional signal since we need Inter_chroma2x2_counter to update 
	//one cycle before blk4x4_inter_calculate_counter
	//----------------------------------------------------------------------------------------
	reg trigger_blk2x2_inter_pred;
	always @ (posedge clk)
		if (reset_n == 1'b0)
			trigger_blk2x2_inter_pred <= 0;
		else if ((IsInterChroma && trigger_blk4x4_inter_pred && mv_below8x8_curr) || 
			(blk4x4_inter_calculate_counter == 4'd1 && Inter_chroma2x2_counter != 0))
			trigger_blk2x2_inter_pred <= 1'b1;
		else
			trigger_blk2x2_inter_pred <= 1'b0; 
	//----------------------------------------------------------------------------------------
	//Inter motion vector for current 4x4 luma/chroma block or 2x2 chroma block
	//	Inter_blk_mvx,Inter_blk_mvy
	//----------------------------------------------------------------------------------------
	reg [7:0] Inter_blk_mvx,Inter_blk_mvy;
	always @ (blk4x4_rec_counter or mv_below8x8_curr or Inter_chroma2x2_counter 
	   	or IsInterLuma or IsInterChroma or mv_is16x16  
		or mvx_CurrMb0 or mvx_CurrMb1 or mvx_CurrMb2 or mvx_CurrMb3
		or mvy_CurrMb0 or mvy_CurrMb1 or mvy_CurrMb2 or mvy_CurrMb3)
		//Inter luma
		if (IsInterLuma)
			begin
				if (mv_is16x16)
					begin	Inter_blk_mvx <= mvx_CurrMb0[7:0];  Inter_blk_mvy <= mvy_CurrMb0[7:0]; end
				else
					case (mv_below8x8_curr)
						1'b0:
						case (blk4x4_rec_counter[3:2])
							2'b00:begin	Inter_blk_mvx <= mvx_CurrMb0[7:0];  Inter_blk_mvy <= mvy_CurrMb0[7:0]; end
							2'b01:begin	Inter_blk_mvx <= mvx_CurrMb1[7:0];  Inter_blk_mvy <= mvy_CurrMb1[7:0]; end
							2'b10:begin	Inter_blk_mvx <= mvx_CurrMb2[7:0];  Inter_blk_mvy <= mvy_CurrMb2[7:0]; end
							2'b11:begin	Inter_blk_mvx <= mvx_CurrMb3[7:0];  Inter_blk_mvy <= mvy_CurrMb3[7:0]; end
						 endcase
						 1'b1:
						case (blk4x4_rec_counter)
							0 :begin Inter_blk_mvx <= mvx_CurrMb0[7:0];  Inter_blk_mvy <= mvy_CurrMb0[7:0];   end
							1 :begin Inter_blk_mvx <= mvx_CurrMb0[15:8]; Inter_blk_mvy <= mvy_CurrMb0[15:8];  end
							2 :begin Inter_blk_mvx <= mvx_CurrMb0[23:16];Inter_blk_mvy <= mvy_CurrMb0[23:16]; end
							3 :begin Inter_blk_mvx <= mvx_CurrMb0[31:24];Inter_blk_mvy <= mvy_CurrMb0[31:24]; end
							4 :begin Inter_blk_mvx <= mvx_CurrMb1[7:0];  Inter_blk_mvy <= mvy_CurrMb1[7:0];   end
							5 :begin Inter_blk_mvx <= mvx_CurrMb1[15:8]; Inter_blk_mvy <= mvy_CurrMb1[15:8];  end
							6 :begin Inter_blk_mvx <= mvx_CurrMb1[23:16];Inter_blk_mvy <= mvy_CurrMb1[23:16]; end
							7 :begin Inter_blk_mvx <= mvx_CurrMb1[31:24];Inter_blk_mvy <= mvy_CurrMb1[31:24]; end
							8 :begin Inter_blk_mvx <= mvx_CurrMb2[7:0];  Inter_blk_mvy <= mvy_CurrMb2[7:0];   end
							9 :begin Inter_blk_mvx <= mvx_CurrMb2[15:8]; Inter_blk_mvy <= mvy_CurrMb2[15:8];  end
							10:begin Inter_blk_mvx <= mvx_CurrMb2[23:16];Inter_blk_mvy <= mvy_CurrMb2[23:16]; end
							11:begin Inter_blk_mvx <= mvx_CurrMb2[31:24];Inter_blk_mvy <= mvy_CurrMb2[31:24]; end
							12:begin Inter_blk_mvx <= mvx_CurrMb3[7:0];  Inter_blk_mvy <= mvy_CurrMb3[7:0];   end
							13:begin Inter_blk_mvx <= mvx_CurrMb3[15:8]; Inter_blk_mvy <= mvy_CurrMb3[15:8];  end
							14:begin Inter_blk_mvx <= mvx_CurrMb3[23:16];Inter_blk_mvy <= mvy_CurrMb3[23:16]; end
							15:begin Inter_blk_mvx <= mvx_CurrMb3[31:24];Inter_blk_mvy <= mvy_CurrMb3[31:24]; end
							default:begin Inter_blk_mvx <= 0;Inter_blk_mvy <= 0; end
						endcase
					endcase
			end
		//Inter chroma
		else if (IsInterChroma)
			begin
				if (mv_is16x16)
					begin	Inter_blk_mvx <= mvx_CurrMb0[7:0];  Inter_blk_mvy <= mvy_CurrMb0[7:0]; end
				else	
					case (blk4x4_rec_counter[1:0])
						2'b00:
						if (mv_below8x8_curr)	//chroma2x2 prediction
							case (Inter_chroma2x2_counter)
								3:begin Inter_blk_mvx <= mvx_CurrMb0[7:0];  Inter_blk_mvy <= mvy_CurrMb0[7:0];   end
								2:begin Inter_blk_mvx <= mvx_CurrMb0[15:8]; Inter_blk_mvy <= mvy_CurrMb0[15:8];  end
								1:begin Inter_blk_mvx <= mvx_CurrMb0[23:16];Inter_blk_mvy <= mvy_CurrMb0[23:16]; end
								0:begin Inter_blk_mvx <= mvx_CurrMb0[31:24];Inter_blk_mvy <= mvy_CurrMb0[31:24]; end
							endcase
						else 				//chroma 4x4 prediction
							begin Inter_blk_mvx <= mvx_CurrMb0[7:0];  Inter_blk_mvy <= mvy_CurrMb0[7:0];   end
						2'b01:
						if (mv_below8x8_curr)	//need chroma2x2 prediction
							case (Inter_chroma2x2_counter)
								3:begin Inter_blk_mvx <= mvx_CurrMb1[7:0];  Inter_blk_mvy <= mvy_CurrMb1[7:0];   end
								2:begin Inter_blk_mvx <= mvx_CurrMb1[15:8]; Inter_blk_mvy <= mvy_CurrMb1[15:8];  end
								1:begin Inter_blk_mvx <= mvx_CurrMb1[23:16];Inter_blk_mvy <= mvy_CurrMb1[23:16]; end
								0:begin Inter_blk_mvx <= mvx_CurrMb1[31:24];Inter_blk_mvy <= mvy_CurrMb1[31:24]; end
							endcase
						else 				//chroma 4x4 prediction
							begin Inter_blk_mvx <= mvx_CurrMb1[7:0];  Inter_blk_mvy <= mvy_CurrMb1[7:0];   end
						2'b10:
						if (mv_below8x8_curr)	//chroma2x2 prediction
							case (Inter_chroma2x2_counter)
								3:begin Inter_blk_mvx <= mvx_CurrMb2[7:0];  Inter_blk_mvy <= mvy_CurrMb2[7:0];   end
								2:begin Inter_blk_mvx <= mvx_CurrMb2[15:8]; Inter_blk_mvy <= mvy_CurrMb2[15:8];  end
								1:begin Inter_blk_mvx <= mvx_CurrMb2[23:16];Inter_blk_mvy <= mvy_CurrMb2[23:16]; end
								0:begin Inter_blk_mvx <= mvx_CurrMb2[31:24];Inter_blk_mvy <= mvy_CurrMb2[31:24]; end
							endcase
						else 				//chroma 4x4 prediction
							begin Inter_blk_mvx <= mvx_CurrMb2[7:0];  Inter_blk_mvy <= mvy_CurrMb2[7:0];   end
						2'b11:
						if (mv_below8x8_curr)	//chroma2x2 prediction
							case (Inter_chroma2x2_counter)
								3:begin Inter_blk_mvx <= mvx_CurrMb3[7:0];  Inter_blk_mvy <= mvy_CurrMb3[7:0];   end
								2:begin Inter_blk_mvx <= mvx_CurrMb3[15:8]; Inter_blk_mvy <= mvy_CurrMb3[15:8];  end
								1:begin Inter_blk_mvx <= mvx_CurrMb3[23:16];Inter_blk_mvy <= mvy_CurrMb3[23:16]; end
								0:begin Inter_blk_mvx <= mvx_CurrMb3[31:24];Inter_blk_mvy <= mvy_CurrMb3[31:24]; end
							endcase
						else 				//chroma 4x4 prediction
							begin Inter_blk_mvx <= mvx_CurrMb3[7:0];  Inter_blk_mvy <= mvy_CurrMb3[7:0];   end
					endcase
			end
		else
			begin Inter_blk_mvx <= 0;  Inter_blk_mvy <= 0;   end
	//----------------------------------------------------------------------------------------
	//Describes the offset of each blk4x4 inside a MB
	//----------------------------------------------------------------------------------------
	// xOffset = 0  for 0,2,8, 10	yOffset = 0  for 0, 1, 4, 5
	// xOffset = 4  for 1,3,9, 11	yOffset = 4  for 2, 3, 6, 7
	// xOffset = 8  for 4,6,12,14	yOffset = 8  for 8, 9, 12,13
	// xOffset = 12 for 5,7,13,15	yOffset = 12 for 10,11,14,15
	reg [3:0] xOffsetL,yOffsetL;
	always @ (IsInterLuma or mv_below8x8_curr or blk4x4_rec_counter[2] or blk4x4_rec_counter[0])
		if (IsInterLuma)
			begin
				if (!mv_below8x8_curr)
					xOffsetL <= (blk4x4_rec_counter[2])? 4'd8:4'd0;
				else
					case ({blk4x4_rec_counter[2],blk4x4_rec_counter[0]})
						2'b00:xOffsetL <= 4'd0;
						2'b01:xOffsetL <= 4'd4;
						2'b10:xOffsetL <= 4'd8;
						2'b11:xOffsetL <= 4'd12;
					endcase
			end
		else
			xOffsetL <= 0;
			
	always @ (IsInterLuma or mv_below8x8_curr or blk4x4_rec_counter[3] or blk4x4_rec_counter[1])
		if (IsInterLuma)
			begin
				if (!mv_below8x8_curr)
					yOffsetL <= (blk4x4_rec_counter[3])? 4'd8:4'd0;
				else
					case ({blk4x4_rec_counter[3],blk4x4_rec_counter[1]})
						2'b00:yOffsetL <= 4'd0;
						2'b01:yOffsetL <= 4'd4;
						2'b10:yOffsetL <= 4'd8;
						2'b11:yOffsetL <= 4'd12;
					endcase
			end
		else
			yOffsetL <= 0;
	
	reg [2:0] xOffsetC,yOffsetC;
	always @ (IsInterChroma or mv_below8x8_curr or blk4x4_rec_counter[0] or Inter_chroma2x2_counter[0])
		if (IsInterChroma)
			begin
				if (mv_below8x8_curr == 1'b0)
					xOffsetC <= (blk4x4_rec_counter[0] == 1'b0)? 3'd0:3'd4;
				else 
					case (blk4x4_rec_counter[0])
						1'b0:xOffsetC <= (Inter_chroma2x2_counter[0] == 1'b1)? 3'd0:3'd2;
						1'b1:xOffsetC <= (Inter_chroma2x2_counter[0] == 1'b1)? 3'd4:3'd6;
					endcase
			end
		else
			xOffsetC <= 0; 
			
	always @ (IsInterChroma or mv_below8x8_curr or blk4x4_rec_counter[1] or Inter_chroma2x2_counter[1])
		if (IsInterChroma)
			begin
				if (mv_below8x8_curr == 1'b0)
					yOffsetC <= (blk4x4_rec_counter[1] == 1'b0)? 3'd0:3'd4;
				else 
					case (blk4x4_rec_counter[1])
						1'b0:yOffsetC <= (Inter_chroma2x2_counter[1] == 1'b1)? 3'd0:3'd2;
						1'b1:yOffsetC <= (Inter_chroma2x2_counter[1] == 1'b1)? 3'd4:3'd6;
					endcase
			end
		else
			yOffsetC <= 3'd0;
	//----------------------------------------------------------------------------------------
	//Integer position of each left-up-most pixel  of a 8x8/4x4/2x2 blk
	//----------------------------------------------------------------------------------------		
	wire [8:0] xIntL_unclip,yIntL_unclip;	// 2's complement,bit[8] is the sign bit
	wire [7:0] xIntC_unclip,yIntC_unclip;	// 2's complement,bit[7] is the sign bit
	assign xIntL_unclip = (IsInterLuma)?   ({1'b0,mb_num_h,4'b0} + xOffsetL + {{3{Inter_blk_mvx[7]}},Inter_blk_mvx[7:2]}):0;
	assign yIntL_unclip = (IsInterLuma)?   ({1'b0,mb_num_v,4'b0} + yOffsetL + {{3{Inter_blk_mvy[7]}},Inter_blk_mvy[7:2]}):0;
	assign xIntC_unclip = (IsInterChroma)? ({1'b0,mb_num_h,3'b0} + xOffsetC + {{3{Inter_blk_mvx[7]}},Inter_blk_mvx[7:3]}):0;
	assign yIntC_unclip = (IsInterChroma)? ({1'b0,mb_num_v,3'b0} + yOffsetC + {{3{Inter_blk_mvy[7]}},Inter_blk_mvy[7:3]}):0; 
	
	wire [8:0] xInt_org_unclip;
	wire [8:0] yInt_org_unclip;
	assign xInt_org_unclip = (IsInterLuma)? xIntL_unclip:{xIntC_unclip[7],xIntC_unclip};
	assign yInt_org_unclip = (IsInterLuma)? yIntL_unclip:{yIntC_unclip[7],yIntC_unclip};
	assign xInt_org_unclip_1to0 = xInt_org_unclip[1:0];
	//----------------------------------------------------------------------------------------
	//Fractional motion vector for both luma and chroma
	//----------------------------------------------------------------------------------------		
	wire [3:0] pos_FracL;
	wire Is_InterChromaCopy;//If chroma is predicted by direct copy,calculate cycle would reduce
							//from 16 cycles to 4 cycles
	
	assign xFracL = (IsInterLuma)?   Inter_blk_mvx[1:0]:0;
	assign yFracL = (IsInterLuma)?   Inter_blk_mvy[1:0]:0;
	assign xFracC = (IsInterChroma)? Inter_blk_mvx[2:0]:0;
	assign yFracC = (IsInterChroma)? Inter_blk_mvy[2:0]:0;
	assign pos_FracL = {xFracL,yFracL};
	assign Is_InterChromaCopy = (IsInterChroma && xFracC == 0 && yFracC == 0)? 1'b1:1'b0;
	
	//----------------------------------------------------------------------------------------
	//Inter prediction step control counter
	//---------------------------------------------------------------------------------------- 
	//1.Preload integer pels counter
	//	If block partition equals 8x8 or above,preload only at first 4x4 block of each 8x8block
	//  If block partition is 8x4,4x8 or 4x4,  preload at each 4x4 block
	always @ (posedge clk)
		if (reset_n == 1'b0)
			blk4x4_inter_preload_counter <= 0;
		//luma
		else if (trigger_blk4x4_inter_pred && IsInterLuma)
			begin
				if (!mv_below8x8_curr && blk4x4_rec_counter[1:0] == 2'b00)
					case (pos_FracL)
						`pos_Int                          :blk4x4_inter_preload_counter <= (xInt_org_unclip[1:0] == 2'b00)? 6'd17:6'd25;
						`pos_f,`pos_q,`pos_i,`pos_k,`pos_j:blk4x4_inter_preload_counter <= 6'd53;
						`pos_d,`pos_h,`pos_n              :blk4x4_inter_preload_counter <= (xInt_org_unclip[1:0] == 2'b00)? 6'd27:6'd40;
						`pos_a,`pos_b,`pos_c              :blk4x4_inter_preload_counter <= 6'd33;
						`pos_e,`pos_g,`pos_p,`pos_r       :blk4x4_inter_preload_counter <= 6'd49;
					endcase
				else if (mv_below8x8_curr)	//partition below 8x8block
					case (pos_FracL)
						`pos_Int						              :blk4x4_inter_preload_counter <= (xInt_org_unclip[1:0] == 2'b00)? 6'd5:6'd9;
						`pos_f,`pos_q,`pos_i,`pos_k,`pos_j:blk4x4_inter_preload_counter <= 6'd28;
						`pos_d,`pos_h,`pos_n			        :blk4x4_inter_preload_counter <= (xInt_org_unclip[1:0] == 2'b00)? 6'd10:6'd19;
						`pos_a,`pos_b,`pos_c			        :blk4x4_inter_preload_counter <= 6'd13;
						`pos_e,`pos_g,`pos_p,`pos_r		    :blk4x4_inter_preload_counter <= 6'd24;
					endcase	
			end
		//chroma
		else if (trigger_blk4x4_inter_pred && IsInterChroma && mv_below8x8_curr == 1'b0)
			begin
				if (xFracC == 0 && yFracC == 0)
					blk4x4_inter_preload_counter <= (xInt_org_unclip[1:0] == 2'b00)? 6'd5:6'd9;
				else
					blk4x4_inter_preload_counter <= 6'd11;
			end
		else if (trigger_blk2x2_inter_pred && IsInterChroma && mv_below8x8_curr == 1'b1)
			begin
				if (xFracC == 0 && yFracC == 0)
					blk4x4_inter_preload_counter <= (xInt_org_unclip[1:0] == 2'b11)? 6'd5:6'd3;
				else
					blk4x4_inter_preload_counter <= (xInt_org_unclip[1]   == 1'b0 )? 6'd4:6'd7;
			end
		else if (blk4x4_inter_preload_counter != 0)
			blk4x4_inter_preload_counter <= blk4x4_inter_preload_counter - 1;
		
	//2.Calculate counter
	always @ (posedge clk)
		if (reset_n == 1'b0)
			blk4x4_inter_calculate_counter <= 0;
		//luma
		else if (IsInterLuma && ((!mv_below8x8_curr && (
										(blk4x4_rec_counter[1:0] == 2'b00 && blk4x4_inter_preload_counter == 1) || 
										(blk4x4_rec_counter[1:0] != 2'b00 && trigger_blk4x4_inter_pred))) ||
								(mv_below8x8_curr && blk4x4_inter_preload_counter == 1))) 
			case (pos_FracL)
				`pos_j,`pos_f,`pos_q:blk4x4_inter_calculate_counter <= 4'd5;
				`pos_i,`pos_k       :blk4x4_inter_calculate_counter <= 4'd8;
				default             :blk4x4_inter_calculate_counter <= 4'd4;
			endcase
		//chroma
		else if (blk4x4_inter_preload_counter == 1 && IsInterChroma == 1'b1)
			case (mv_below8x8_curr)
				1'b0:blk4x4_inter_calculate_counter <= 4'd4;
				1'b1:blk4x4_inter_calculate_counter <= 4'd1;
			endcase
		else if (blk4x4_inter_calculate_counter != 0)
			blk4x4_inter_calculate_counter <= blk4x4_inter_calculate_counter - 1;
	
	assign end_of_one_blk4x4_inter = (blk4x4_inter_calculate_counter == 4'd1 &&
	((IsInterChroma && mv_below8x8_curr && Inter_chroma2x2_counter == 2'b00) ||
	!(IsInterChroma && mv_below8x8_curr)));
	//----------------------------------------------------------------------------------------
	//Inter prediction reference frame RAM read control
	//----------------------------------------------------------------------------------------
	assign ref_frame_RAM_rd = ((IsInterLuma || IsInterChroma) && blk4x4_inter_preload_counter != 6'd0 && blk4x4_inter_preload_counter != 6'd1);
	
	//compared with blk4x4_inter_preload_counter,blk4x4_inter_preload_counter_m2 has some advantages
	//during some pos_FracL for vertical memory address decoding
	wire [5:0] blk4x4_inter_preload_counter_m2;	
	assign blk4x4_inter_preload_counter_m2 = (blk4x4_inter_preload_counter == 6'd0 || blk4x4_inter_preload_counter == 6'd1)?
												6'd0:(blk4x4_inter_preload_counter - 2);
				
	//xInt_curr_offset: offset from the left-upper most pixel of current block,ranging -2 ~ +10.
	//After each preload cycle,xInt_curr_offset will increase 4
	reg [4:0] xInt_curr_offset;
	always @ (IsInterLuma or mv_below8x8_curr or pos_FracL or xFracC or yFracC 
		or xInt_org_unclip[1:0] or blk4x4_inter_preload_counter_m2 or blk4x4_inter_preload_counter)
		if (blk4x4_inter_preload_counter != 6'd0 && blk4x4_inter_preload_counter != 6'd1)
			begin
				if (IsInterLuma)
					begin
						if (!mv_below8x8_curr)
							case (pos_FracL)
								`pos_f,`pos_q,`pos_i,`pos_k,`pos_j:
								case (blk4x4_inter_preload_counter_m2[1:0])
									2'b00:xInt_curr_offset <= 5'b01010; //+10
									2'b01:xInt_curr_offset <= 5'b00110; //+6
									2'b10:xInt_curr_offset <= 5'b00010; //+2
									2'b11:xInt_curr_offset <= 5'b11110; //-2
								endcase
								`pos_d,`pos_h,`pos_n:
								if (xInt_org_unclip[1:0] == 2'b00)
									xInt_curr_offset <= (blk4x4_inter_preload_counter_m2[0])? 4'b0:4'b0100; //+0 or +4
								else
									case (blk4x4_inter_preload_counter_m2)
										6'd38,6'd35,6'd32,6'd29,6'd26,6'd23,6'd20,6'd17,6'd14,6'd11,6'd8,6'd5,6'd2:
										xInt_curr_offset <= 5'b0; 			//+0
										6'd37,6'd34,6'd31,6'd28,6'd25,6'd22,6'd19,6'd16,6'd13,6'd10,6'd7,6'd4,6'd1:
										xInt_curr_offset <= 5'b00100;		//+4
										default:xInt_curr_offset <= 5'b01000;//+8
									endcase
								`pos_a,`pos_b,`pos_c:
								case (blk4x4_inter_preload_counter_m2[1:0])
									2'b00:xInt_curr_offset <= 5'b01010; //+10
									2'b01:xInt_curr_offset <= 5'b00110; //+6
									2'b10:xInt_curr_offset <= 5'b00010; //+2
									2'b11:xInt_curr_offset <= 5'b11110; //-2
								endcase
								`pos_Int:
								if (xInt_org_unclip[1:0] == 2'b00)
									xInt_curr_offset <= (blk4x4_inter_preload_counter_m2[0])? 5'b0:5'b0100; //+0 or +4
								else
									case (blk4x4_inter_preload_counter_m2)
										6'd23,6'd20,6'd17,6'd14,6'd11,6'd8,6'd5,6'd2:
										xInt_curr_offset <= 5'b00000;	   	//+0
										6'd22,6'd19,6'd16,6'd13,6'd10,6'd7,6'd4,6'd1:
										xInt_curr_offset <= 5'b00100;	   	//+4
										default:xInt_curr_offset <= 5'b01000;//+8
									endcase
								`pos_e,`pos_g,`pos_p,`pos_r:
								case (blk4x4_inter_preload_counter_m2)
									6'd47,6'd44,6'd5,6'd2:
									xInt_curr_offset <= 5'b00000;	//+0
									6'd46,6'd43,6'd4,6'd1:
									xInt_curr_offset <= 5'b00100;	//+4
									6'd45,6'd42,6'd3,6'd0:
									xInt_curr_offset <= 5'b01000;	//+8
									default:
									case (blk4x4_inter_preload_counter_m2[1:0])
										2'b00:xInt_curr_offset <= 5'b00010; //+2
										2'b01:xInt_curr_offset <= 5'b11110; //-2
										2'b10:xInt_curr_offset <= 5'b01010; //+10
										2'b11:xInt_curr_offset <= 5'b00110; //+6
									endcase
								endcase
							endcase
						else		//block partition below 8x8
							case (pos_FracL)
								`pos_f,`pos_q,`pos_i,`pos_k,`pos_j:
								case (blk4x4_inter_preload_counter_m2)
									6'd26,6'd23,6'd20,6'd17,6'd14,6'd11,6'd8,6'd5,6'd2:xInt_curr_offset <= 5'b11110;//-2
									6'd25,6'd22,6'd19,6'd16,6'd13,6'd10,6'd7,6'd4,6'd1:xInt_curr_offset <= 5'b00010;//+2
									default:xInt_curr_offset <= 5'b00110;											//+6
								endcase
								`pos_d,`pos_h,`pos_n:
								if (xInt_org_unclip[1:0] == 2'b00)
									xInt_curr_offset <= 5'b0;	//+0
								else
									xInt_curr_offset <= (blk4x4_inter_preload_counter_m2[0])? 5'b0:5'b00100;//+0 or +4
								`pos_a,`pos_b,`pos_c:
								case (blk4x4_inter_preload_counter_m2)
									6'd11,6'd8,6'd5,6'd2:xInt_curr_offset <= 5'b11110;	//-2
									6'd10,6'd7,6'd4,6'd1:xInt_curr_offset <= 5'b00010;	//+2
									default:xInt_curr_offset <= 5'b00110;				//+6
								endcase
								`pos_Int:
								if (xInt_org_unclip[1:0] == 2'b00)
									xInt_curr_offset <= 5'b0;	//+0
								else
									xInt_curr_offset <= (blk4x4_inter_preload_counter_m2[0])? 5'b0:5'b00100;	//+0 or +4
								`pos_e,`pos_g,`pos_p,`pos_r:
								case (blk4x4_inter_preload_counter_m2)
									6'd22,6'd20,6'd3,6'd1:xInt_curr_offset <= 5'b0;			//+0	
									6'd21,6'd19,6'd2,6'd0:xInt_curr_offset <= 5'b00100;		//+4 
									6'd18,6'd15,6'd12,6'd9,6'd6:xInt_curr_offset <= 5'b11110;//-2
									6'd17,6'd14,6'd11,6'd8,6'd5:xInt_curr_offset <= 5'b00010;//+2
									6'd16,6'd13,6'd10,6'd7,6'd4:xInt_curr_offset <= 5'b00110;//+6
									default:xInt_curr_offset <= 5'b0;
								endcase
							endcase
					end
				else	//IsInterChroma
					begin
						if (!mv_below8x8_curr)
							begin
								if (xFracC == 0 && yFracC == 0)
									begin
										if (xInt_org_unclip[1:0] == 2'b00)
											xInt_curr_offset <= 5'b0;
										else
											xInt_curr_offset <= (blk4x4_inter_preload_counter_m2[0] == 1'b1)? 5'b0:5'b0100;
									end
								else
									xInt_curr_offset <= (blk4x4_inter_preload_counter_m2[0] == 1'b1)? 5'b0:5'b0100;
							end
						else //mv_below8x8_curr == 1'b1
							begin
								if (xFracC == 0 && yFracC == 0)
									begin
										if (xInt_org_unclip[1:0] == 2'b11)	// 4 preload cycles
											xInt_curr_offset <= (blk4x4_inter_preload_counter_m2[0] == 1'b1)? 5'b0:5'b0100;
										else
											xInt_curr_offset <= 0;
									end
								else
									begin
										if (xInt_org_unclip[1] == 1'b0)
											xInt_curr_offset <= 0;
										else
											xInt_curr_offset <= (blk4x4_inter_preload_counter_m2[0] == 1'b1)? 5'b0:5'b0100;
									end
							end
					end
			end
		else	//blk4x4_inter_preload_counter == 0 || blk4x4_inter_preload_counter == 1 
			xInt_curr_offset <= 5'b0; 
	
	//Derive unclipped x pos for each preload cycle
	wire [8:0] xInt_addr_unclip;
	assign xInt_addr_unclip = xInt_org_unclip + {{4{xInt_curr_offset[4]}},xInt_curr_offset};
	
	//x addr clipped:x address in pixels
	reg [7:0] xInt_addr;
	always @ (xInt_addr_unclip or IsInterLuma or IsInterChroma)
		if (xInt_addr_unclip[8] == 1'b1)	//negative
			xInt_addr <= 0;
		else if (IsInterLuma)
			xInt_addr <= (xInt_addr_unclip[7:0] > (`pic_width - 4))? 8'd172:xInt_addr_unclip[7:0];
		else if (IsInterChroma)
			xInt_addr <= (xInt_addr_unclip[7:0] > (`half_pic_width - 4))? 8'd84:xInt_addr_unclip[7:0];
		else
			xInt_addr <= 0;
			
	//yInt_p1:when loading from Xth line to (X-1)th line,yInt_p1 is set to 1'b1 at the last
	//loading cycle of current Xth line
	reg yInt_p1;
	always @ (IsInterLuma or mv_below8x8_curr or pos_FracL or xFracC or yFracC 
		or blk4x4_inter_preload_counter or blk4x4_inter_preload_counter_m2 or xInt_org_unclip[1:0] or xInt_org_unclip[1])
		if (blk4x4_inter_preload_counter != 6'd0 && blk4x4_inter_preload_counter != 6'd1)
			begin
				if (IsInterLuma)
					case (mv_below8x8_curr)
						1'b0:
						case (pos_FracL)
							`pos_f,`pos_q,`pos_i,`pos_k,`pos_j:
							yInt_p1 <= (blk4x4_inter_preload_counter_m2[1:0] == 2'b00)? 1'b1:1'b0;
							`pos_d,`pos_h,`pos_n:
							if (xInt_org_unclip[1:0] == 2'b00)
								yInt_p1 <= (blk4x4_inter_preload_counter_m2[0] == 1'b0)? 1'b1:1'b0;
							else
								case (blk4x4_inter_preload_counter_m2)
									6'd36,6'd33,6'd30,6'd27,6'd24,6'd21,6'd18,6'd15,6'd12,6'd9,6'd6,6'd3,6'd0:
									yInt_p1 <= 1'b1;
									default:yInt_p1 <= 1'b0;
								endcase
							`pos_a,`pos_b,`pos_c:
							yInt_p1 <= (blk4x4_inter_preload_counter_m2[1:0] == 2'b00)? 1'b1:1'b0;
							`pos_Int:
							if (xInt_org_unclip[1:0] == 2'b00)
								yInt_p1 <= (blk4x4_inter_preload_counter_m2[0] == 1'b0)? 1'b1:1'b0;
							else
								case (blk4x4_inter_preload_counter_m2)
									6'd21,6'd18,6'd15,6'd12,6'd9,6'd6,6'd3,6'd0:yInt_p1 <= 1'b1;
									default:									yInt_p1 <= 1'b0;
								endcase
							`pos_e,`pos_g,`pos_p,`pos_r:
							case (blk4x4_inter_preload_counter_m2)
								6'd45,6'd42,6'd3,6'd0:yInt_p1 <= 1'b1;
								6'd6,6'd10,6'd14,6'd18,6'd22,6'd26,6'd30,6'd34,6'd38:yInt_p1 <= 1'b1;
								default:yInt_p1 <= 1'b0;
							endcase
						endcase
						1'b1:		//block partition below 8x8
						case (pos_FracL)
							`pos_f,`pos_q,`pos_i,`pos_k,`pos_j:
							case (blk4x4_inter_preload_counter_m2)
								6'd24,6'd21,6'd18,6'd15,6'd12,6'd9,6'd6,6'd3,6'd0:yInt_p1 <= 1'b1;
								default:yInt_p1 <= 1'b0;
							endcase
							`pos_d,`pos_h,`pos_n:
							if (xInt_org_unclip[1:0] == 2'b00)
								yInt_p1 <= 1'b1;	
							else
								yInt_p1 <= (blk4x4_inter_preload_counter_m2[0] == 1'b0)? 1'b1:1'b0;
							`pos_a,`pos_b,`pos_c:
							case (blk4x4_inter_preload_counter_m2)
								5'd9,5'd6,5'd3,5'd0	:yInt_p1 <= 1'b1;
								default				:yInt_p1 <= 1'b0;
							endcase
							`pos_Int:
							if (xInt_org_unclip[1:0] == 2'b00)
								yInt_p1 <= 1'b1;
							else
								yInt_p1 <= (blk4x4_inter_preload_counter_m2[0] == 1'b0)? 1'b1:1'b0;
							`pos_e,`pos_g,`pos_p,`pos_r:
							case (blk4x4_inter_preload_counter_m2)
								6'd21,6'd19,6'd2,6'd0		:yInt_p1 <= 1'b1;
								6'd4,6'd7,6'd10,6'd13,6'd16	:yInt_p1 <= 1'b1;
								default						:yInt_p1 <= 1'b0;
							endcase
						endcase
					endcase
				else	//IsInterChroma
					case (mv_below8x8_curr)
						1'b0:
						if (xFracC == 0 && yFracC == 0)
							begin
								if (xInt_org_unclip[1:0] == 2'b00)
									yInt_p1 <= 1'b1;
								else
									yInt_p1 <= (blk4x4_inter_preload_counter_m2[0] == 1'b0)? 1'b1:1'b0;
							end
						else
							yInt_p1 <= (blk4x4_inter_preload_counter_m2[0] == 1'b0)? 1'b1:1'b0;
						1'b1:
						if (xFracC == 0 && yFracC == 0)
							begin
								if (xInt_org_unclip[1:0] != 2'b11)
									yInt_p1 <= 1'b1;
								else
									yInt_p1 <= (blk4x4_inter_preload_counter_m2[0] == 1'b0)? 1'b1:1'b0;
							end
						else
							begin
								if (xInt_org_unclip[1] == 1'b0)
									yInt_p1 <= 1'b1;
								else 
									yInt_p1 <= (blk4x4_inter_preload_counter_m2[0] == 1'b0)? 1'b1:1'b0;
							end
					endcase
			end
		else	// blk4x4_inter_preload_counter == 0 || blk4x4_inter_preload_counter == 1			
			yInt_p1 <= 1'b0; 
	
	//Derive unclipped y pos for each preload cycle
	reg [8:0] yInt_addr_unclip;
	always @ (posedge clk)
		if (reset_n == 1'b0)
			yInt_addr_unclip <= 0;
		else if ((IsInterLuma && (trigger_blk4x4_inter_pred && (mv_below8x8_curr ||
			(!mv_below8x8_curr && blk4x4_rec_counter[1:0] == 2'b00)))) ||
			(IsInterChroma && (!mv_below8x8_curr && trigger_blk4x4_inter_pred) ||
							   (mv_below8x8_curr && trigger_blk2x2_inter_pred)))
			begin
				if (IsInterLuma)	//Luma
					case (pos_FracL)
						`pos_a,`pos_b,`pos_c,`pos_Int:
						yInt_addr_unclip <= yInt_org_unclip;
						default:				//need -2 here
						yInt_addr_unclip <= yInt_org_unclip + 9'b111111110;
					endcase
				else			   //Chroma
					yInt_addr_unclip <= yInt_org_unclip;
			end
		else if (blk4x4_inter_preload_counter_m2 != 0 && yInt_p1 == 1'b1)
			yInt_addr_unclip <= yInt_addr_unclip + 1;
		
	//y addr clipped
	reg [7:0] yInt_addr;
	always @ (yInt_addr_unclip or IsInterLuma or IsInterChroma)
		if (yInt_addr_unclip[8] == 1'b1)	//negative
			yInt_addr <= 0;
		else if (IsInterLuma)
			yInt_addr <= (yInt_addr_unclip[7:0] > (`pic_height - 1))? 8'd143:yInt_addr_unclip[7:0];
		else if (IsInterChroma)
			yInt_addr <= (yInt_addr_unclip[7:0] > (`half_pic_height - 1))? 8'd71:yInt_addr_unclip[7:0];
		else
			yInt_addr <= 0;
		
	wire [12:0] offset_constant;
	wire [10:0] yInt_addr_x11;
	wire [12:0]	offset_yInt_addr;
	assign offset_constant = (IsInterLuma)? 0:((IsInterChroma)? ((blk4x4_rec_counter < 5'd20)? 13'd6336:13'd7920):0); 
	assign yInt_addr_x11 = {yInt_addr,3'b0} + {2'b0,yInt_addr,1'b0} + {3'b0,yInt_addr};
	assign offset_yInt_addr = (IsInterLuma)? {yInt_addr_x11,2'b0}:{1'b0,yInt_addr_x11,1'b0};
	assign ref_frame_RAM_rd_addr = (offset_constant + {8'b0,xInt_addr[7:2]}) + {1'b0,offset_yInt_addr};
	
	//----------------------------------------------------------------------------------------
	//Inter prediction output control: from LPE or from CPE
	//----------------------------------------------------------------------------------------
	always @ (IsInterLuma or IsInterChroma or Is_InterChromaCopy 
		or blk4x4_inter_calculate_counter or pos_FracL
		or Inter_pix_copy0 or Inter_pix_copy1 or Inter_pix_copy2 or Inter_pix_copy3
		or LPE0_out or LPE1_out or LPE2_out or LPE3_out
		or CPE0_out or CPE1_out or CPE2_out or CPE3_out) 
		if (IsInterLuma && blk4x4_inter_calculate_counter != 0)
			begin
				Inter_blk4x4_pred_output_valid <= 2'b01;
				case (pos_FracL)
					`pos_Int:
					begin
						Inter_pred_out0 <= Inter_pix_copy0;Inter_pred_out1 <= Inter_pix_copy1;
						Inter_pred_out2 <= Inter_pix_copy2;Inter_pred_out3 <= Inter_pix_copy3;
					end
					`pos_i,`pos_k:
					if (blk4x4_inter_calculate_counter == 4'd7 || blk4x4_inter_calculate_counter == 4'd5 || 
						blk4x4_inter_calculate_counter == 4'd3 || blk4x4_inter_calculate_counter == 4'd1)
						begin
							Inter_pred_out0 <= LPE0_out;Inter_pred_out1 <= LPE1_out;
							Inter_pred_out2 <= LPE2_out;Inter_pred_out3 <= LPE3_out;
						end
					else
						begin
							Inter_pred_out0 <= 0;Inter_pred_out1 <= 0;Inter_pred_out2 <= 0;Inter_pred_out3 <= 0;
						end
					default:
					if (blk4x4_inter_calculate_counter == 4'd4 || blk4x4_inter_calculate_counter == 4'd3 || 
						blk4x4_inter_calculate_counter == 4'd2 || blk4x4_inter_calculate_counter == 4'd1)
						begin
							Inter_pred_out0 <= LPE0_out;Inter_pred_out1 <= LPE1_out;
							Inter_pred_out2 <= LPE2_out;Inter_pred_out3 <= LPE3_out;
						end
					else
						begin
							Inter_pred_out0 <= 0;Inter_pred_out1 <= 0;Inter_pred_out2 <= 0;Inter_pred_out3 <= 0;
						end
				endcase
			end
		else if (IsInterChroma && blk4x4_inter_calculate_counter != 0)
			begin
				Inter_pred_out0 <= (Is_InterChromaCopy)? Inter_pix_copy0:CPE0_out;
				Inter_pred_out1 <= (Is_InterChromaCopy)? Inter_pix_copy1:CPE1_out;
				Inter_pred_out2 <= (Is_InterChromaCopy)? Inter_pix_copy2:CPE2_out;
				Inter_pred_out3 <= (Is_InterChromaCopy)? Inter_pix_copy3:CPE3_out;
				Inter_blk4x4_pred_output_valid <= 2'b10;
			end
		else
			begin
				Inter_pred_out0 <= 0;Inter_pred_out1 <= 0;Inter_pred_out2 <= 0;Inter_pred_out3 <= 0;
				Inter_blk4x4_pred_output_valid <= 2'b00;
			end
endmodule