⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rb1_decoder.v

📁 H.264的CABAC的常规码的解码过程
💻 V
字号:
module RB1_decoder(rangeOut, offsetOut, rom2_address, bin_0, modelValue_out, used_bin_num, 
					same_ctxIdxLPS, last_pStateIdx, readReg, ctxIdx, codIRange, codIOffset, rom2_in_data,
					IsNotB0, modelValue_in, next_modelValue_in, group_effective, /*syntaxElement, 
					complement, */dec_mode, clk, rst);
	output [8:0] 	rangeOut;
	output [8:0] 	offsetOut;			
	output [5:0] 	rom2_address;
	output 			bin_0;
	output [6:0]	modelValue_out;
	output [3:0]	used_bin_num;		//how many bins the RB1 used.
	output [31:0]	same_ctxIdxLPS;
	output [5:0]	last_pStateIdx;		//in case RB2_decoder decoding out of 'LPS', renew pStateIdx;
	
	reg [8:0]		rangeOut;
	reg [8:0]		offsetOut;
	reg [5:0]		rom2_address;
	reg 			bin_0;
	reg [6:0]		modelValue_out;		//send to RB2
	reg [3:0] 		used_bin_num;  
	
	wire [31:0]		same_ctxIdxLPS;
	wire [5:0]		last_pStateIdx;
		
	input [15:0]	readReg;
	input [8:0]		ctxIdx;
	input [8:0]		codIRange;
	input [8:0]		codIOffset;
	input [111:0]	rom2_in_data;
	input 			IsNotB0;
	input [6:0]		modelValue_in;		//obtain model
	input [6:0]		next_modelValue_in;
	input 			group_effective;			//1: indicate RAM is effective;
	//input [4:0]		syntaxElement;
	//input [1:0]		complement;
	input [2:0]		dec_mode;	  
	input 			clk;
	input 			rst;
	
	reg [7:0] 		FODValue;				//FOD input value (8 bits);
	reg [2:0] 		FODNum;					//FOD output value (3 bits);
	reg [8:0]		reserve_ctxIdx;			//restore ctxIdx
	reg [111:0]		prefetched_rLPS;		//pre-feteched rLPS;
	reg [31:0]		next_rangeLPS;
	reg [39:0] 		last_rangeLPS;			//+8 bits last state 
	reg [5:0] 		pStateIdx;	
//	reg 			rLPS_effective;			//rLPS is effective
//	reg 			IsPrefetched;			
	reg [8:0]		rangeNew;
	reg [8:0]		offsetNew;		   
	reg 			IsValMPS;				//is valMPS in last cycles 
//	reg [2:0]		position_rLPS;			//Indicate which rLPS should be appled
	reg [7:0]		codIRangeLPS;			//rLPS to decoded	   
//	reg 			prefetched_load;		//judge if load prefetched value;
											//only rLPS_effective = 1 
	reg [1:0]		samectxIdx_state;			//to record the status of in same ctxIdx;
											
	//reg [1:0] state, next_state;  //not effecient to use state machine, because it waste a cycle
	
	wire [1:0] 		qCodIRangeIdx;		//qCodIRangeIdx = (codIRange >> 6) & 3;
	wire 			valMPS;					
	
	assign qCodIRangeIdx = codIRange[7:6];
	//assign valMPS = modelValue_in[6];
	assign same_ctxIdxLPS = next_rangeLPS[31:0]; //
	assign last_pStateIdx = last_rangeLPS[37:32];
	
	always @(posedge clk or negedge rst)
		begin
			if(!rst)
				begin 
					//rLPS_effective <= 0;
					rom2_address <= 0;
				//	rangeOut <= 0;
				//	offsetOut <= 0;
				//	bin_0 <= 0;		 
				//	modelValue_out <= 0;
				//	used_bin_num <= 0;
					reserve_ctxIdx <= 0;
				//	prefetch_rLPS <= 0;
				//	IsPrefetched <= 0; 
				//	prefetched_load <= 0;
					samectxIdx_state <= 0;
				end					  
			else
				begin
					if(group_effective)	
						begin
							reserve_ctxIdx <= ctxIdx;
						end
				
					if(!IsNotB0)
						begin
							if(reserve_ctxIdx == ctxIdx)
								begin		
									//rLPS_effective <= 1;
									if(samectxIdx_state < 2)	//maxim is 2
										begin
											samectxIdx_state <= samectxIdx_state + 1;
										end
									case(samectxIdx_state)
										2'b00:	//havn't pre-fetched next ctxIdx value
										begin
											rom2_address <= next_modelValue_in[5:0];
										end											
											
										default: //have pre-fetched next ctxIdx value 
										begin
											rom2_address <= pStateIdx;
										end	
									endcase	 								
								end	
							else if(reserve_ctxIdx == (ctxIdx + 1))	   //not effecient as I want.
								begin					
								//	rLPS_effective <= 1;  
									samectxIdx_state <= 0;
									rom2_address <= modelValue_in[6:0];	//to obtain next 32-bits rLPS
								//	IsPrefetched <= 0;				
								//	position_rLPS <= 3'b100;
								end	
							else   							//Be careful! because RAM_management maybe not completed 
								begin																				
								//	rLPS_effective <= 0;	  
									samectxIdx_state <= 0;
									if(group_effective)
										begin
										//	IsPrefetched <= 0;	 
										//	prefetched_load <= 0;
											rom2_address <= modelValue_in[6:0];	 
											samectxIdx_state <= 0;
										end	
								end	
						end	
						else   								//IsNotB0, coeff_abs_level_minus1, continous decoded
							begin 	  
								//IsPrefetched <= 0;			//never to take ctxIdx + 1;
								if(reserve_ctxIdx == ctxIdx) 
									begin
									//	rLPS_effective <= 1;   
										samectxIdx_state <= 0;
										rom2_address <= pStateIdx + 2;  //	
									//	position_rLPS <= 3'b000;
									end	
								else
									begin
									//	rLPS_effective <= 0;
										if(group_effective)
											begin
												rom2_address <= modelValue_in[5:0];
											end	
									end	
							end	
				end	
		end	
	   
		always @(codIRange or codIOffset or dec_mode or qCodIRangeIdx or samectxIdx_state or ctxIdx or reserve_ctxIdx or IsValMPS or modelValue_in or readReg or rom2_in_data)
			begin	 
				rangeNew = codIRange;
				offsetNew = codIOffset;
				codIRangeLPS = 0;
				//prefetched_rLPS = 0;
				
				if(((dec_mode == 3'b000) || (dec_mode == 3'b100)) && ((reserve_ctxIdx == ctxIdx) || (reserve_ctxIdx == (ctxIdx + 1))))
					begin
						if(reserve_ctxIdx == ctxIdx)
							begin
								case(samectxIdx_state)
									0:
									begin  
											case(qCodIRangeIdx)
											2'b00:
											begin
												codIRangeLPS = rom2_in_data[39:32];	
											end										
											
											2'b01:
											begin
												codIRangeLPS = rom2_in_data[47:40];
											end			  
											
											2'b10:
											begin
												codIRangeLPS = rom2_in_data[55:48];
											end									  
											
											2'b11:
											begin
												codIRangeLPS = rom2_in_data[63:56];
											end	
										endcase	
										next_rangeLPS = rom2_in_data[31:0];
										last_rangeLPS = rom2_in_data[103:64];
									end
									
									2:		//first state
									begin
										case(qCodIRangeIdx)
											2'b00:
											begin
												codIRangeLPS = rom2_in_data[39:32];	
											end										
											
											2'b01:
											begin
												codIRangeLPS = rom2_in_data[47:40];
											end			  
											
											2'b10:
											begin
												codIRangeLPS = rom2_in_data[55:48];
											end									  
											
											2'b11:
											begin
												codIRangeLPS = rom2_in_data[63:56];
											end	
										endcase	
										next_rangeLPS = rom2_in_data[31:0];
										last_rangeLPS = rom2_in_data[103:64];
									end	   
									
									1:								 		//second state
									begin	
										prefetched_rLPS = rom2_in_data; 	//restore it 
										case({IsValMPS, qCodIRangeIdx})
											3'b000:
											begin
												codIRangeLPS = last_rangeLPS[7:0];
											end									
											
											3'b001:
											begin
												codIRangeLPS = last_rangeLPS[15:8];
											end									 
											
											3'b010:
											begin
												codIRangeLPS = last_rangeLPS[23:16];
											end									  
											
											3'b011:
											begin
												codIRangeLPS = last_rangeLPS[31:24];
											end	
											
											3'b100:
											begin
												codIRangeLPS = next_rangeLPS[7:0];
											end									
											
											3'b101:
											begin
												codIRangeLPS = next_rangeLPS[15:8];
											end									 
											
											3'b110:
											begin
												codIRangeLPS = next_rangeLPS[23:16];
											end									  
											
											3'b111:
											begin
												codIRangeLPS = next_rangeLPS[31:23];
											end	
										endcase	
									end
									
									default:
									begin
										codIRangeLPS = 0;
									end
									
								endcase	
							end
						else //if(ctxIdx == (reserve_ctxIdx + 1))
							begin							  
								next_rangeLPS = prefetched_rLPS[31:0];
								last_rangeLPS = prefetched_rLPS[103:64];
								case(qCodIRangeIdx)
										2'b00:
										begin
											codIRangeLPS = prefetched_rLPS[39:32];	
										end										
											
										2'b01:
										begin
											codIRangeLPS = prefetched_rLPS[47:40];
										end			  
											
										2'b10:
										begin
											codIRangeLPS = prefetched_rLPS[55:48];
										end									  
											
										2'b11:
										begin
											codIRangeLPS = prefetched_rLPS[63:56];
										end										
								endcase	
							end
						mainOperation;		//main decoding process;
						rangeOut = rangeNew;
						offsetOut = offsetNew;
					end
					else if(ctxIdx == 276)		//termination
						begin
							termination;
						end	
			end	
			
		task mainOperation;
		begin
			rangeNew = rangeNew - codIRangeLPS;
			if(offsetNew < rangeNew)		//valMPS
				begin
				 	bin_0 = modelValue_in[6];	
					IsValMPS = 1; 	  
					pStateIdx = modelValue_in[5:0];
					if(pStateIdx < 62)
						begin
							pStateIdx = pStateIdx + 1;
							modelValue_out[5:0] = pStateIdx;
						end	
						
					if(!rangeNew[8])		//codIRange < 0x100 need left shift one time
					begin  
						rangeNew = rangeNew << 1;
						offsetNew = offsetNew << 1;
						offsetNew[0] = readReg[0]; 
						used_bin_num = 1;
					end	
				end							  
			else							//valLPS
				begin									
					bin_0 = !modelValue_in[6];  //valure of LPS
					IsValMPS = 0;
					offsetNew = offsetNew - rangeNew;
					rangeNew = codIRangeLPS;
					pStateIdx = modelValue_in[5:0];
					if(pStateIdx == 0)
						begin
						 	modelValue_out[6] = !modelValue_in[6]; //valMPS = 1 - valMPS
						end		
					if(reserve_ctxIdx == ctxIdx)	
						pStateIdx = last_rangeLPS[37:32];
					else if(reserve_ctxIdx == (ctxIdx + 1))
						pStateIdx = prefetched_rLPS[101:96];
						
					modelValue_out[5:0] = pStateIdx;		//renew pStateIdx;	
					FODValue = rangeNew[7:0];	
					firstOneDetect;
					used_bin_num = FODNum;
					case(FODNum)		//FODNum = 1--7
						1:	
						begin
							rangeNew = rangeNew << 1;
							offsetNew = offsetNew << 1;	
							offsetNew[0] = readReg[0];
						end							   
						
						2:	
						begin
							rangeNew = rangeNew << 2;
							offsetNew = offsetNew << 2;
							offsetNew[1:0] = readReg[1:0];
						end							   
						
						3:	
						begin
							rangeNew = rangeNew << 3;
							offsetNew = offsetNew << 3;	
							offsetNew[2:0] = readReg[2:0];
						end							   
						
						4:	
						begin
							rangeNew = rangeNew << 4;
							offsetNew = offsetNew << 4;	
							offsetNew[3:0] = readReg[3:0];
						end							   
						
						5:	
						begin
							rangeNew = rangeNew << 5;
							offsetNew = offsetNew << 5;	
							offsetNew[4:0] = readReg[4:0];
						end							   
						
						6:	
						begin
							rangeNew = rangeNew << 6;
							offsetNew = offsetNew << 6;	
							offsetNew = readReg[5:0];
						end							   
						
						7:	
						begin
							rangeNew = rangeNew << 7;
							offsetNew = offsetNew << 7;
							offsetNew = readReg[6:0];
						end							   
						
						default:
						begin
							rangeNew = rangeNew << 1;  		//this should never be reached!
							offsetNew = offsetNew << 1;
							offsetNew = readReg[0];
						end							
					endcase	
				end	
			end	
		endtask	 
		
		task firstOneDetect;
		reg out1;
		begin
			out1 = |FODValue[7:4];	
			
			if(out1)
			begin
				if(FODValue[7])
					FODNum = 0;
				else if(FODValue[6])
					FODNum = 1;
				else if(FODValue[5])
					FODNum = 2;
				else
					FODNum = 3; 
			end
			else
				begin
					if(FODValue[3])
						FODNum = 0;
					else if(FODValue[2])
						FODNum = 1;
					else if(FODValue[1])
						FODNum = 2;
					else
						FODNum = 3;
						
					FODNum = FODNum + 4;
				end		
		end	
	endtask
	
		task termination;
		begin
			rangeNew = rangeNew - 2;
			if(offsetNew < rangeNew)
				begin
					bin_0 = 0;
					if(!rangeNew[8])		//codIRange < 0x100 need left shift one time
					begin					   
						FODValue = rangeNew[7:0];	
						firstOneDetect;
						//rangeNew = rangeNew << FODNum;
						//offsetNew = offsetNew << FODNum;	
						case(FODNum)		//FODNum = 1--7
						1:	
						begin
							rangeNew = rangeNew << 1;
							offsetNew = offsetNew << 1;	
							offsetNew[0] = readReg[0];
						end							   
						
						2:	
						begin
							rangeNew = rangeNew << 2;
							offsetNew = offsetNew << 2;
							offsetNew[1:0] = readReg[1:0];
						end							   
						
						3:	
						begin
							rangeNew = rangeNew << 3;
							offsetNew = offsetNew << 3;	
							offsetNew[2:0] = readReg[2:0];
						end							   
						
						4:	
						begin
							rangeNew = rangeNew << 4;
							offsetNew = offsetNew << 4;	
							offsetNew[3:0] = readReg[3:0];
						end							   
						
						5:	
						begin
							rangeNew = rangeNew << 5;
							offsetNew = offsetNew << 5;	
							offsetNew[4:0] = readReg[4:0];
						end							   
						
						6:	
						begin
							rangeNew = rangeNew << 6;
							offsetNew = offsetNew << 6;	
							offsetNew = readReg[5:0];
						end							   
						
						7:	
						begin
							rangeNew = rangeNew << 7;
							offsetNew = offsetNew << 7;
							offsetNew = readReg[6:0];
						end							   
						
						default:
						begin
							rangeNew = rangeNew << 1;  		//this should never be reached!
							offsetNew = offsetNew << 1;
							offsetNew = readReg[0];
						end							
					endcase	
					used_bin_num = FODNum;
				end	
				else
					begin
						bin_0 = 1;
					end	
			end	
		end	
	endtask
					
			
endmodule	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -