カメラのIF見直し中

もっと簡単にできないかと思って見直し中。
Fenrir's BLogのfenrirさんのVHDLを眺めると、結構シンプルにできてるので、自分のソースは複雑すぎでへんな部分が多すぎなのかとか思い始める。
今は単純にhsyncとvsyncを取ってるだけなので、もっと厳密にした方が良いかも。
バッファにhsyncとvsyncの前の状態を保存して、スタート位置判定を厳密にするとか?
だとすれば単純に前と今の状態がバッファに保存するとして考えると
hsync,vsyncが前の状態が0、今の状態が1だとすればカメラのフレームデータの出力がスタート
hsyncが前の状態が1、今の状態が0だとすればライン終了
hsyncが前の状態が0、今の状態が1だとすればライン開始
vsyncが前の状態が1、今の状態が0だとすればカメラのフレームデータの出力が終了(この場合hsyncは無視)
の4現象が基本なのでこれにあわせたステートをデータ入力部とカウンタと状態レジスタに入れてやるというのが良いかもしんない。単純に上の現象でIF部分の動作を決めてデータカウンタも動かす。
IFの部分でどの大きさのデータがくるというのが分からないほうがいいかもしんない。単純に受動的に有効なデータだけを淡々受信し続けるというのがやはり理想。エラー処理はIFのモジュールでやらない方が良いかもIFのモジュールはできるだけ単純で確実の動作することが重要。


否検証版(そんなののせるなよver)
とりあえずちまちま訂正してTCM8230用からTCM8240用に変更
ただタイミング部分が若干ずれるかもとかおもってたり。

// File Name	:TCM8240
// Author		:ippei-r
// Date 		: 2008/12/28
// Description	: camera IF
// Rev			: 01



`timescale 1ns / 10ps


//TOSHIBA TCM8240MD interface module
module TCM8240MD_IF (
	
	//module reset 
	SI_nRST,

	//カメラの出力クロックはカメラより出力されてDCMに入れる
	//DCMよりモジュールに入力する
	//external input → DCM → This module
	DCMO_CAMCLK,
	
	//external input FPGA外部入力
	EI_CAMVSYNC,	//camera vertical syncronization pulse input
	EI_CAMHSYNC,	//camera holizontal syncronization pulse inuput
	EI_CAMDAT,		//camera data output (8bit)
	
	//external output FPGA外部出力
	EO_CAMRST,	//camera input rest

	//module output 
	MO_CAMLINECNT,	    //camera line counter
	MO_CAMPIXELCNT,	    //camera pixel counter
	MO_CAMDATVALID,	    //camera output data valid
	MO_CAMDAT,	    //camera output data

	MO_DATSTATE,			//カメラデータのステート

	//module input
	MI_CAMDATFMT,	    //camera picture data format

    );

//system input
input SI_nRST;
input DCMO_CAMCLK;	    //DCMから出力されるカメラのデータクロック

//exetnal input
input EI_CAMVSYNC;	    //カメラのvertical 端子
input EI_CAMHSYNC;	    //カメラのholizontanl 端子
input [7:0] EI_CAMDAT;   //カメラのデータ出力端子
//input EI_CAMRST;	    //カメラのリセット
//カメラのデータ出力クロックは最上位のmoduleで入力してDCMへ

//extenal output
output EO_CAMRST;

//module output
output [10:0] MO_CAMLINECNT;	    //1frame最大1024line
output [10:0] MO_CAMPIXELCNT;	    //1line最大1280pixel
output MO_CAMDATVALID;		    //
output [31:0]MO_CAMDAT;		    
output [2:0] MO_DATSTATE;
//RGBの場合は1pixel2byte,YUV422は2pixelで4byte

//module input
input [1:0] MI_CAMDATFMT;		    //2'b00:YUV422,2'b01:RGB565,2'b11:JPEG(未実装)

//////////////////////////////////////////////////////////////////
//reg
reg [2:0] datcnt;
reg [10:0] vercnt;
reg [10:0] holcnt;
reg datvld;

reg [31:0] pixeldat;

reg [2:0]state;
reg [1:0]buf_hsync;
reg [1;0]buf_vsync;
//wire



//parameter
parameter YUV422 = 0;
parameter RGB565 = 1;
/////////////////////////////////////////////////////////////////////
//state 
/////////////////////////////////////////////////////////////////////
//sync get
always @(posedge DCMO_CAMCLK) begin
	if(!SI_nRST) begin
		buf_hsync[1:0] <= 2'b00;
		buf_vsync[1:0] <= 2'b00;
	end else begin
		buf_hsync[1:0] <= {buf_hsync[0],EI_CAMHSYNC};
		buf_vsync[1:0] <= {buf_vsync[0],EI_CAMVSYNC};
	end
end

//state
always @posedge DCMO_CAMCLK) begin
	if(!SI_nRST) state[2:0] <= 3'b000;
	else begin
		if(~buf_vsync[1] & buf_vsync[0])	state[2] <= 1;
		else 								state[2] <= 0;
		if(~buf_hsync[1] & buf_hsync[0])	state[1] <= 1;
		else								state[1] <= 0;
		if(buf_hsync[1] & buf_hsync[0])		state[0] <= 1;
		else								state[0] <= 0;
	end
end

//data valid
always @(posedge DCMO_CAMCLK) begin
	if(!SI_nRST) begin		
		datcnt <= 0;
		datvld <= 0;
	end else if(EI_CAMHSYNC) begin
		if(MI_CAMDATFMT == 2'b00) begin
			//YUV422
			if(datcnt == 3'h3) begin	
				datcnt <= 0;
				datvld <= 1;
			end else begin
				datcnt <= datcnt + 1;
				datvld <= 0;
			end
		end else if(MI_CAMDATFMT == 2'b01) begin
			//RGB565
			if(datcnt == 3'h1) begin 
				datcnt <= 0;
				datvld <= 1;
			end else begin		
				datcnt <= datcnt + 1;
				datvld <= 0;
			end
		end
	end else begin
		datcnt <= 0;
		datvld <= 0;
	end
end

///////////////////////////////////////////////////////////////////////////
//counter
///////////////////////////////////////////////////////////////////////////

always @(posedge DCMO_CAMCLK) begin
	if(!SI_nRST) 
		begin
			vercnt[10:0] <= 10'h000;
			holcnt[10;0] <= 10'h000;
		end 
	else if(state[2]) 
		begin
			//FLAMESTART
			vercnt[10:0] <= 10'h001;
			holcnt[10:0] <= 10'h001;
		end
	else if(state[0])
		begin
			//LINESTART
			holcnt[10;0] <= 10'h001;
			vercnt[10:0] <= vercnt[10:0] + 10'h001; 
		end
	else if(state[0])
		begin
			//DATERECEIVE
			holcnt[10:0] <= holcnt[10:0] + 10'h001;
			vercnt[10:0] <= vercnt[10:0];
		end
end

//////////////////////////////////////////////////////////////////////////
//pixel get
//////////////////////////////////////////////////////////////////////////

always @(posedge DCMO_CAMCLK) begin
	if(!SI_nRST)			pixeldat[31:0] <= 0;
	else					pixeldat[31:0] <= {pixeldat[23:0],EI_CAMDAT[7:0]};
end

///////////////////////////////////////////////////////////////////////////
//moudule output signal
///////////////////////////////////////////////////////////////////////////
assign MO_CAMLINECNT[10:0] 				= vercnt[10:0];
assign MO_CAMPIXELCNT[10:0]				= holcnt[10:0];
assign MO_CAMDATVALID					= datvld;
assign MO_CAMDAT[31:0]					= pixeldat[31:0];						
assign MO_DATSTATE[2:0]					= state[2:0];
assign EO_CAMRST						= SI_nRST;

endmodule