yuvRGBコンバーター

とりあえず大まかに完成。出力データ有効とかはまだ。
とりあえず眠いのでシミュレーションはまた明日。
 
追記
なんか駄目だな-と思ったら右シフトの幅が足らなかった。
計算がうまくいってなかった。

追記(17:20)
これでたぶん大丈夫だと思う。

//
//	YUV422_RGB_CONVERT
//	CNV.v
//
//	Rev00:2008/11/30 ippei-r new
//

`timescale 1 ns / 10 ps

//YUV422 → RGB 変換 モジュール
module yuv422_cnv(
	
	//system input
	SI_nRST,
	SI_CLK,

	//module input
	MI_U,
	MI_Y1,
	MI_V,
	MI_Y2,
	MI_DATVLD,

	//module output
	MO_R1,
	MO_G1,
	MO_B1,
	MO_R2,
	MO_G2,
	MO_B2
//	MO_DATVLD
	
	);

//system input
input		SI_nRST;
input		SI_CLK;

//module output
input		[7:0]	MI_U;
input		[7:0]	MI_Y1;
input		[7:0]	MI_V;
input		[7:0]	MI_Y2;
input		MI_DATVLD;

//module output
output		[7:0]	MO_R1;
output		[7:0]	MO_G1;
output		[7:0]	MO_B1;
output		[7:0]	MO_R2;
output		[7:0]	MO_G2;
output		[7:0]	MO_B2;
//output		MO_DATVLD;

/////////////////////////////////////////////////////////////////////////
//reg
/////////////////////////////////////////////////////////////////////////

//register
reg	signed		[17:0]	RG_U;
reg	signed		[35:0]	RG_Yn;
reg	signed		[17:0]	RG_V;
reg	signed		[35:0]	RG_Yn1;

//RGB値格納

reg 			[7:0]	RG_R1;
reg				[7:0]	RG_R2;
reg				[7:0]	RG_G1;
reg				[7:0]	RG_G2;
reg				[7:0]	RG_B1;
reg				[7:0]	RG_B2;

//wait
reg				[4:0]	CALC_WAIT;		//演算待ち用カウントレジスタ

//wire
wire 			[35:0]	W_R_V;
wire			[35:0]	W_G_U;
wire			[35:0]	W_G_V;
wire			[35:0]	W_B_U;

wire			[35:0]	R1;
wire			[35:0]	R2;
wire			[35:0]	G1;
wire			[35:0]	G2;
wire			[35:0]	B1;
wire			[35:0]	B2;



//parameter
//演算係数すでに9bitシフト済みの値
//RのVの係数 1.402<<9=	717.824=718
parameter		R_V_coff = 	718;
//GのUの係数 0.344<<9=	176.128
parameter		G_U_coff =	-176;
//GのVの係数 0.714<<9 = 365.568
parameter		G_V_coff = 	-366;
//BのUの係数 1.772<<9 = 907.264
parameter		B_U_coff =	907;

/////////////////////////////////////////////////////////////////
//data input
/////////////////////////////////////////////////////////////////
//RG_Yn input
always @(posedge SI_CLK) begin
	if(!SI_nRST)			RG_Yn[35:0]	<=	0;
	else if(MI_DATVLD)		RG_Yn[35:0]	<=	{MI_Y1[7:0],9'h000};
end

//RG_Yn1 input
always @(posedge SI_CLK) begin
	if(!SI_nRST) 			RG_Yn1[35:0]	<=	0;
	else if(MI_DATVLD)		RG_Yn1[35:0]	<=	{MI_Y2[7:0],9'h000};
end

//RG_U input
always @(posedge SI_CLK) begin
	if(!SI_nRST)			RG_U[17:0]	<=	0;
	else if(MI_DATVLD) begin	
		if(MI_U[7])		RG_U[17:0]	<=	{10'b1111111111,MI_U[7:0]};
		else			RG_U[17:0]	<=	{10'b0000000000,MI_U[7:0]};
	end
end

//RG_V input
always @(posedge SI_CLK) begin
	if(!SI_nRST)			RG_V[17:0]	<= 	0;
	else if(MI_DATVLD) begin
		if(MI_V[7])		RG_V[17:0]	<=	{10'b1111111111,MI_V[7:0]};
		else			RG_V[17:0]	<=	{10'b0000000000,MI_V[7:0]};
	end
end


//演算待ち時間
always @(posedge SI_CLK) begin
	if(!SI_nRST)			CALC_WAIT 	<=	0;
	else if(CALC_WAIT == 2'b00101) begin
		CALC_WAIT <= 0;	
		//MO_DATVLD <= 1;
	end else if(MI_DATVLD) 	CALC_WAIT <= CALC_WAIT + 1;
end


////////////////////////////////////////////////////////////////
//data 右シフト
///////////////////////////////////////////////////////////////
//R1
always @(posedge SI_CLK) begin
	if(!SI_nRST)			RG_R1 <= 0;
	else //if(CALC_WAIT == 5'b00100) 
		begin
		if(R1[35] == 1)		RG_R1 <= 0;		//負の数
		//正の数で255以上
		else if(R1[34] || R1[33] || R1[32] || R1[31] || R1[30] ||
				R1[29] || R1[28] || R1[27] || R1[26] || R1[25] ||
				R1[24] || R1[23] || R1[21] || R1[20] || R1[19] ||
				R1[18] || R1[17])		
			RG_R1[7:0] <= 8'b11111111;
		else
		RG_R1[7:0] <= R1[16:9];
	end
end

//R2
always @(posedge SI_CLK) begin
	if(!SI_nRST)			RG_R2 <= 0;
	else //if(CALC_WAIT == 5'b00100) 
		begin
		if(R2[35] == 1)		RG_R2 <= 0;		//負の数
		//正の数で255以上
		else if(R2[34] || R2[33] || R2[32] || R2[31] || R2[30] ||
				R2[29] || R2[28] || R2[27] || B2[26] || B2[25] ||
				B2[24] || B2[23] || B2[21] || B2[20] || B2[19] ||
				B2[18] || B2[17])		
			RG_R2[7:0] <= 255;
		else
		RG_R2[7:0] <= R2[16:9];
	end
end

//G1
always @(posedge SI_CLK) begin
	if(!SI_nRST)			RG_G1 <= 0;
	else //if(CALC_WAIT == 5'b00100) 
		begin
		if(G1[35] == 1)		RG_G1 <= 0;		//負の数
		//正の数で255以上
		else if(G1[34] || G1[33] || G1[32] || G1[31] || G1[30] ||
				G1[29] || G1[28] || G1[27] || G1[26] || G1[25] ||
				G1[24] || G1[23] || G1[21] || G1[20] || G1[19] ||
				G1[18] || G1[17])		
			RG_G1[7:0] <= 255;
		else
		RG_G1[7:0] <= G1[16:9];
	end
end

//G2
always @(posedge SI_CLK) begin
	if(!SI_nRST)			RG_G2 <= 0;
	else //if(CALC_WAIT == 5'b00100) 
		begin
		if(G2[35] == 1)		RG_G2 <= 0;		//負の数
		//正の数で255以上
		else if(G2[34] || G2[33] || G2[32] || G2[31] || G2[30] ||
				G2[29] || G2[28] || G2[27] || G2[26] || G2[25] ||
				G2[24] || G2[23] || G2[21] || G2[20] || G2[19] ||
				G2[18] || G2[17])		
			RG_G2[7:0] <= 255;
		else
		RG_G2[7:0] <= G2[16:9];
	end
end

//B1
always @(posedge SI_CLK) begin
	if(!SI_nRST)			RG_B1 <= 0;
	else //if(CALC_WAIT == 5'b00100) 
		begin
		if(B1[35] == 1)		RG_B1 <= 0;		//負の数
		//正の数で255以上
		else if(B1[34] || B1[33] || B1[32] || B1[31] || B1[30] ||
				B1[29] || B1[28] || B1[27] || B1[26] || B1[25] ||
				B1[24] || B1[23] || B1[21] || B1[20] || B1[19] ||
				B1[18] || B1[17])		
			RG_B1[7:0] <= 255;
		else
		RG_B1[7:0] <= B1[16:9];
	end
end

//B2
always @(posedge SI_CLK) begin
	if(!SI_nRST)			RG_B2 <= 0;
	else //if(CALC_WAIT == 5'b00100) 
		begin
		if(B2[35] == 1)		RG_B2[7:0] <= 0;		//負の数
		//正の数で255以上
		else if(B2[34] || B2[33] || B2[32] || B2[31] || B2[30] ||
				B2[29] || B2[28] || B2[27] || B2[26] || B2[25] ||
				B2[24] || B2[23] || B2[21] || B2[20] || B2[19] ||
				B2[18] || B2[17])		
			RG_B2[7:0] <= 255;
		else
		RG_B2[7:0] <= B2[16:9];
	end
end

///////////////////////////////////////////////////////////////
//calculate
///////////////////////////////////////////////////////////////

//乗算
assign	W_R_V = R_V_coff * RG_V;
assign	W_G_V = G_V_coff * RG_V;
assign	W_G_U = G_U_coff * RG_U;
assign	W_B_U = B_U_coff * RG_U;

//加算
assign	R1 = RG_Yn + W_R_V;
assign	R2 = RG_Yn1 + W_R_V;
assign	G1 = RG_Yn + W_G_U + W_G_V;
assign	G2 = RG_Yn1 + W_G_U + W_G_V;
assign	B1 = RG_Yn + W_B_U;
assign	B2 = RG_Yn1 + W_B_U;

assign	MO_R1 = RG_R1;
assign	MO_R2 = RG_R2;
assign	MO_G1 = RG_G1;
assign	MO_G2 = RG_G2;
assign	MO_B1 = RG_B1;
assign	MO_B2 = RG_B2;

endmodule