FC2カウンター FPGAの部屋 CMOSカメラから画像を入力してディスプレイへ出力14(CMOSカメラの出力が出た!)
FC2ブログ

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

FPGAの部屋

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

CMOSカメラから画像を入力してディスプレイへ出力14(CMOSカメラの出力が出た!)

CMOSカメラから画像を入力してディスプレイへ出力13(もしかしたらRESETはアクティブハイ?)”でCMOSカメラのRESETはアクティブハイのようなので、CMOSカメラのRESETを0固定にしてみた。

 n_cam_reset <= '0'; -- OV7640のRESETはアクティブハイ

としたら、CMOSカメラから出力が出てきた。うれしかった!
Camera_Disp_25_091020.png

HREFやデータが出ている。正常に動いているようだ。単にリセットしなければ良かったのか?
VSYNCの後の最初にHREFが1になって、master_sync が1の時を拡大したの下の図。
Camera_Disp_26_091020.png

それらしくデータが出ている。cam_ydata_2d の3B, 3D, 3D, 3F... のデータがYデータのようだ。これでもしかしてうまくいっているかな?と思ってVGAディスプレイをつないでみたが、かなりおかしい画像だった。それでもCMOSカメラの画像という雰囲気はある。
Camera_Disp_28_091020.jpg

同期信号はOKだがデータがおかしいような表示だ。まだどこかがおかしい。
ChipScopeにメモリ関係の信号を入れて取りなおしてみた。(下の図)
Camera_Disp_27_091020.png

なかなか良さそうだ。シミュレーションと比べてみると、下にシミュレーションの図を示す。
Camera_Disp_29_091021.png

ピンクの楕円で囲ったmaster_sync が出た1クロック後に、黄色の楕円で囲ったn_mem_rd は0になっている。しかし、1つ前のChipScopeの図ではmaster_sync が出た後のn_mem_rd_OBUF(下から2番目の信号)の値は1である。ここがおかしい。このChipScopeでの結果ではSRAMのデータとFPGAからの書き込みデータがぶつかってしまう。なぜに、シミュレーションと実機の動作が違うのか?
ここでChisScopeで作ったVCDファイルを持ってきておけば、”Veritak3.69C以降におけるModelSimのVHDLシミュレーションとChipScopeの協調検証”でやったようにVeritakを使用して比較できたのだが。。。
VHDLソースを見てみることにした。n_mem_rdがおかしいので、そのコードを見てみる。CamDispCntrl_SRAM.vhdで、下のように書いてある。

 n_mem_rd <= not r_w;


r_w 信号は、synchronizer.vhd が出力している。下にソースを示す。

    -- その他のモジュールの動作は1クロック遅れるので、最初はwrite_stateとなる
    process(cs_rw, cs_sync, cam_href_1d) begin
        case cs_rw is
            when idle_rw =>
                r_w_node <= '1';
                if cs_sync=vsync_deassert and cam_href_1d='1' then
                    ns_rw <= write_state;
                else
                    ns_rw <= idle_rw;
                end if;
            when read_state =>
                r_w_node <= '1';
                if cs_sync=vsync_deassert and cam_href_1d='1' then
                    ns_rw <= read_state;
                else
                    ns_rw <= write_state;
                end if;
            when write_state =>
                r_w_node <= '0';
                if cs_sync=vsync_deassert and cam_href_1d='1' then
                    ns_rw <= read_state;
                else
                    ns_rw <= read_state;
                end if;
        end case;
    end process;
    r_w <= r_w_node;


上のソースで、”if cs_sync=vsync_deassert and cam_href_1d='1' then”はmaster_sync が1になる条件だ。idle_rw ステートに初期化時にいるから、最初にmaster_sync が出るとwrite_state に遷移する。その後はwrite_state, read_state を交互に遷移する。その後、master_sync が出たらread_state に遷移してしまう。これじゃおかしい。
シミュレーションは初期状態を示していて、ChipScopeはそれより後の状態を示している。シミュレーションでそれを確認するためには35ms 程度シミュレーションする必要があるので大変だ。このようにクロック周期と実際の動作のタイムスケールが相当異なる回路ではシミュレーションによる確認が難しい場合がある。
上のソースを下のように修正した。

    -- その他のモジュールの動作は1クロック遅れるので、最初はwrite_stateとなる
    process(cs_rw, cs_sync, cam_href_1d) begin
        case cs_rw is
            when idle_rw =>
                r_w_node <= '1';
                if cs_sync=vsync_deassert and cam_href_1d='1' then
                    ns_rw <= write_state;
                else
                    ns_rw <= idle_rw;
                end if;
            when read_state =>
                r_w_node <= '1';
                if cs_sync=vsync_deassert and cam_href_1d='1' then
                    ns_rw <= write_state;
                else
                    ns_rw <= write_state;
                end if;
            when write_state =>
                r_w_node <= '0';
                if cs_sync=vsync_deassert and cam_href_1d='1' then
                    ns_rw <= write_state;
                else
                    ns_rw <= read_state;
                end if;
        end case;
    end process;
    r_w <= r_w_node;


これでやってみる。たぶん直っていると思う。
  1. 2009年10月21日 04:32 |
  2. 画像処理
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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