カメラの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