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

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

FPGAの部屋

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

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路21(VIO、tcl)

Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路にChipScope ProのVIOを入れて、tclでデータを取得してみることにした。
最初に、回路を変更して、VIOのIPを挿入した。sw0, sw1の2つのスイッチを使用して、sw0が1の時に連続的にCMOSカメラからの画像を取り込むが、sw0が0の時は、CMOSカメラからの画像を取り込まない。結果として、最後のCMOSカメラの画像をずっと表示することになる。つまりデジカメ機能をつけた訳だ。(前回説明済み)次に、DDR2 SDRAMのアドレス入力をVGAコントローラとVIOのSYNC_INに切り替えるスイッチを付けた。それがsw1だ。通常は0で、VGAコントローラのアドレスをDDR2 SDRAMに入力する。これで正常にディスプレイに画像が表示される。次に1にすると、VIOのSYNC_INのアドレスをDDR2 SDRAMに入力する。このモードは、VIOからアドレスを入力して、画像データを取得する場合に使用する。
使用方法としては、sw0を1、sw1を0にしておいて、画像データをディスプレイに表示して、良さそうな画像になったら、sw0を0にして、画像データを取得する。これで静止画が取れたので、sw1を1にして、VIOのSYNC_INからDDR2 SDRAMにアドレスを与える。
SRAMと違って、DDR2 SDRAMは、アドレスを与えるだけではデータは出てこないので、SYNC_INから与えるアドレスデータが違っていたら、DDR2 SDRAMコントローラにアドレスのライト・イネーブルパルスを送るようにしている。出てきたデータはラッチされて、VIOのSYNC_OUTに出てくるので、VIOコンソールに出力するか、tclでファイルに落とす。
下に変更したVerilog ソースを示す。VIOについては、前回のリンクを参照。

    SW_Controller #(
        .frequency_KHz(25000))
    SW_CONT_inst(
        .clk(clk_cam),
        .reset(reset_cam),
        .sw0(sw0),
        .sw1(sw1),
        .sw0_out(capture_ena),
        .sw1_out(vio_on)
    );
    
    CamCaptICON CamCaptICON_inst (
        .CONTROL0(control0) // INOUT BUS [35:0]
    );
    CamCaptVIO CamCaptVIO_inst (
        .CONTROL(control0), // INOUT BUS [35:0]
        .CLK(clk_ddr2), // IN
        .SYNC_IN(sync_in), // IN BUS [63:0]
        .SYNC_OUT(sync_out) // OUT BUS [24:0]
    );

    // sync_outの変化を検知してvio_addr_we を出力する
    always @(posedge clk_ddr2) begin
        if (reset_ddr2) begin
            sync_out_reg1 <= 25'd0;
            sync_out_reg2 <= 25'd0;
        end else begin
            sync_out_reg1 <= sync_out;
            sync_out_reg2 <= sync_out_reg1;
        end
    end
    always @* begin
        if (sync_out_reg1 != sync_out_reg2) // 以前の値と異なるとき
            vio_addr_we <= 1'b1;
        else
            vio_addr_we <= 1'b0;
    end
    
    // first_dword VIOの最初の32ビット
    always @(posedge clk_ddr2) begin
        if (reset_ddr2)
            first_dword <= 1'b1;
        else begin
            if (vio_on && ddr2_rddata_valid)
                first_dword <= 1'b0;
            else
                first_dword <= 1'b1;
        end
    end
    // sync_in 処理
    always @(posedge clk_ddr2) begin
        if (reset_ddr2)
            sync_in <= 64'd0;
        else begin
            if (vio_on & first_dword && ddr2_rddata_valid) begin
                sync_in[63:32] <= ddr2_output_data;
            end
            if (vio_on & ~first_dword && ddr2_rddata_valid) begin
                sync_in[31:0] <= ddr2_output_data;
            end
        end
    end


これで、ChipScope ProのAnalyzerを立ち上げて、VIOコンソールを見た。その様子を下図に示す。
CamDispCntrler_DDR2_36_100831.png

アドレスが0 (SYNC_IN) の時のデータ (SYNC_OUT) が表示されている。これをSYNC_IN(アドレス)を4に変更すると、アドレス4のデータがSYNC_OUTに表示される。
CamDispCntrler_DDR2_37_100831.png

ちなみにSYNC_OUTのデータは4画素分となる。8ビットずつUVVYUVVYと入っているはずだ。これはDDR2 SDRAMのデータ幅16ビットと粒度4で決まってしまう。

つぎにtclスクリプトを書いて、データを取得してみた。試しに34個のデータを取得した。下にコマンド・プロンプトの画面を示す。
CamDispCntrler_DDR2_38_100901.png

アドレス00000と00004の値が上のVIOコンソールに表示された値と同じ値になっているのがわかると思う。これで、同時にcamera_capture_data.txtという名前のファイルに値が書かれる。
CamDispCntrler_DDR2_39_100901.png

これで、UYまたはVYの16ビットデータを307200個取れれば、画像データをすべて取得できる。

(追記)画像データの取得が終わりました。21分程度かかりました。
  1. 2010年09月01日 05:23 |
  2. 画像処理
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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