FC2カウンター FPGAの部屋 Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路11(ChipScope Pro)
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路11(ChipScope Pro)

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路をChipScope Proで観察してみた。
Camera_Contorller.vのcam_cont_afifoのoverflowフラグが1になってしまうのが問題だ。現在のCamera_Contorller.vはカメラのデータが正常に表示されるかを確認するために0からインクリメントしたデータをDDR2 SDRAMに書き込んでいる。Camera_Contorller.vの全ソースを下に示す。

// CAMERA_CONTROLLER
// カメラデータを書き込むためのDDR2 SDRAMアドレスを出力する
// YデータとUVデータを出力する。フォーマットはUYVY
// 2001/07/24:cam_cont_afifoに2つ以上のデータがあることを示すためにrd_data_countを出力ポートに追加する

`default_nettype none

module Camera_Controller (
    input    wire    clk_cam,    // 25MHzのCMOSカメラ用クロック
    input    wire    clk_ddr2,    // 133.33MHzのDDR2 SDRAM用クロック
    input    wire    reset_cam,    // clk_cam 用リセット
    input    wire    reset_ddr2,    // clk_ddr2 用リセット
    input    wire    cam_href_2d,     // CMOSカメラからのHREFのラッチ出力(2クロック遅延)
    input    wire    master_sync,     // 同期信号
    input    wire    [7:0]    cam_data_2d,    // CMOSカメラからの輝度データ
    output    reg        [18:0]    address,    // アドレス
    output    wire    [31:0]    data_out,    // VYUY8ビットフォーマットの画像データ出力
    input    wire    addr_enable,    // アドレス・イネーブル
    input    wire    data_enable,    // データ・イネーブル
    output    wire    afifo_empty,    // cam_cont_afifo はempty 
    output    wire    [3:0]    afifo_rd_data_count,     // cam_cont_afifoのread data count
    output    wire    afifo_overflow, // cam_cont_afifo はoverflow
    output    wire    afifo_underflow    // cam_cont_afifo はunderflow
);
    
    reg [7:0] uv_ff;
    wire afifo_wr_en;
    wire [15:0] afifo_din;
    reg y_pos;
    wire afifo_full;
    
    parameter UV_state =    1'b0;
    parameter Y_state =        1'b1;
    reg YUV_state;
    
    reg    [7:0] count;
    
    // 非同期FIFO Write(16ビット幅、32深度)、Read(32ビット幅、16深度)
    cam_cont_afifo cam_cont_afifo_inst (
        .rst(reset_ddr2),
        .wr_clk(clk_cam),
        .rd_clk(clk_ddr2),
        .din(afifo_din), // Bus [15 : 0] 
        .wr_en(afifo_wr_en),
        .rd_en(data_enable),
        .dout(data_out), // Bus [31 : 0] 
        .full(afifo_full),
        .overflow(afifo_overflow),
        .empty(afifo_empty),
        .underflow(afifo_underflow),
        .rd_data_count(afifo_rd_data_count) // Bus [3 : 0] 
    );
    
    // UまたはVを保存しておくFF、UYVYで出てくるので、UまたはVを保存しておいてYが出てきた時点でcam_cont_afifoに書き込む
    always @(posedge clk_cam) begin
        if (reset_cam)
            uv_ff <= 0;
        else
            uv_ff <= cam_data_2d;
    end
    
    // U,VとYを表すステートマシン
    always @(posedge clk_cam) begin
        if (reset_cam)
            YUV_state <= UV_state;
        else
            case (YUV_state)
                UV_state :
                    if (cam_href_2d)
                        YUV_state <= Y_state;
                    else
                        YUV_state <= UV_state;
                Y_state :
                    YUV_state <= UV_state;
        endcase
    end
    
    // afifo_din はuv_ff とcam_data_2d を連結
    // assign afifo_din = {uv_ff, cam_data_2d};
    assign afifo_din = {count, count};
    // cam_cont_afifo のwr_en はYUV_state がY_state の時
    assign afifo_wr_en = (YUV_state==Y_state) ? 1'b1 : 1'b0;
    
    // テスト用カウンタ
    always @(posedge clk_ddr2) begin
        if (reset_ddr2)
            count <= 0;
        else begin
            if (master_sync)
                count <= 0;
            else if (YUV_state==Y_state)
                count <= count + 8'd1;
        end
    end
    
    // アドレス用カウンタ 640*480 = 307,200(hex 4b000)をカウントする
    always @(posedge clk_ddr2) begin
        if (reset_ddr2)
            address <= 0;
        else begin    
            if (master_sync) // 1フレーム終了したので0に戻す
                address <= 0;
            else if (addr_enable)
                    address <= address + 19'd4; // DDR2 SDRAMは1回の書き込みで4つの16ビットデータを書き込むため
        end
    end
endmodule

`default_nettype wire


cam_cont_afifoには、Core Generator で生成した非同期FIFOを使用している。
ChipScopeで観察した波形を下に示す。
CamDispCntrler_DDR2_23_100809.png

一番上の信号のcamc_afifo_overflowが1の時にトリガーがかかるようになっている。/Cam_Cntrler_inst/cam_cont_afifo_inst/wr_en が非同期FIFOの書き込み信号で、この信号は25MHzで動作する信号だが、ChipScopeのクロックは125MHzなので、複数クロックでトグルしている。/Cam_Cntrler_inst/cam_cont_afifo_inst/rd_en が125MHz動作の信号で、これは1パルスで非同期FIFOの読み出しを行う。
おかしいのは、/cam_cont_afifo_inst/wr_data_countが06から急に3F(青と赤のカーソルで囲まれた部分)になってしまうことだ。それでfullとなって、更に書き込むため overflow してしまうようだ。rd_data_countもおかしい?
どこが悪いのか?良くわからない?もしかして、リセット関係が悪いのだろうか?ヒゲが出てたりして?
  1. 2010年08月09日 19:25 |
  2. 画像処理
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog.fc2.com/tb.php/1550-566e903e
この記事にトラックバックする(FC2ブログユーザー)