« ZYBOでOV7670カメラモジュールのVGA画像を表示する | トップページ | PYNQ-Z1のOverlay読み込みとPythonからのFPGA PLの制御 »

Vivado Constraints Wizardによるクロック・入出力制約の作成

前回のポストで、ZYBOを使って、OV7670カメラのVGA画像が取り込めるようになりましたが、制約条件が未設定でした。VivadoのConstraints Wizardを使うことによってクロックと入出力の制約条件を設定して、Unconstraintsの箇所を消すことができました。制約条件を設定することによって画質が向上したため、回路を正しく動作させるためには制約条件の設定は必須なんだと分かりました。

以下に、Constraints Wizardを使った制約条件の設定方法を記載します。

操作手順

Constraints WizardはVivadoのFlow Navigatorから起動でき、SynthesisとImplementationの両方から起動できます。一旦合成・配置を行なった後だと、どちらから起動しても作成される制約ファイルの内容は同じになるようです。

Constraints Wizard

Wizardを起動します。カメラのPCLKをFCLKで同期化したpclk_sと、HLSとのインタフェースに使っているap_doneが、Generated Clock(ユーザー定義のクロック)の候補として表示されました。ソースクロック(FCLK)の分周率を指定する形式となっており、実際のクロック周波数とは同じになりませんが、ここでは4を指定しました。pclk_sは24MHzなので、100MHz ÷ 4がそれに近い値ということで。

当初はpclk_sの制約条件を”create_clock”コマンドで作成しようとしたのですが、create_clockはプライマリークロックの定義となっているため、create_clockを使うとImplematation時にタイミング違反が発生してしまいます。このようなケースでは、”create_generated_clock”を使うのが正しいのだということが分かりました。

Constraints Wizard-2

Constraints Wizard-3

次に入力遅延を設定します。入力遅延はリファレンスクロック(ここではFCLK)の立ち上がりに対する遅延ということなので、これも実態(PCLKの立ち上がりに対して、実際のデーターはセットアップ時間前に有効になっている)とは異なりますが、1〜2 nsの遅延を指定。

Constraints Wizard input delay

続けて、出力遅延を設定。こちらは、25MHzのVGAクロックの立ち上がりに対するセットアップ・ホールド遅延の設定になります。

Constraints Wizard output delay

次に、非同期クロックドメインを指定する画面が表示されます。下段に3つのエントリが表示されていますが、Non-recommendedということなのでチェックはしていません。この項目にチェックを入れると、"set_clock_groups -asynchronous “の制約が生成されるのですが、オブジェクトに指定されるクロック名が認識できない旨のCritical Waringが合成時に出てしまいました。

20161211 Constraints Wizard Async Clock

最後にWizardを完了。

Constraints Wizard done

以下のエントリが制約ファイルに追加されました。 

create_generated_clock -name ov7670_vram_sys_i/MemRead_0/inst/ap_done -source [get_pins {ov7670_vram_sys_i/processing_system7_0/inst/PS7_i/FCLKCLK[0]}] -divide_by 4 [get_pins {ov7670_vram_sys_i/MemRead_0/inst/ap_CS_fsm_reg[10]/Q}]
create_generated_clock -name ov7670_vram_sys_i/OV7670_camera_hs_0/inst/pclk_s -source [get_pins {ov7670_vram_sys_i/processing_system7_0/inst/PS7_i/FCLKCLK[0]}] -divide_by 4 [get_pins ov7670_vram_sys_i/OV7670_camera_hs_0/inst/pclk_s_reg/Q]
create_clock -period 40.000 -name VIRTUAL_ov7670_vram_sys_i/OV7670_camera_hs_0/inst/pclk_s -waveform {0.000 20.000}
create_clock -period 40.000 -name VIRTUAL_clk25_ov7670_vram_sys_clk_wiz_0_0 -waveform {-3.333 16.667}
set_input_delay -clock [get_clocks clk_fpga_0] -min -add_delay 2.000 [get_ports {data[*]}]
set_input_delay -clock [get_clocks clk_fpga_0] -max -add_delay 3.000 [get_ports {data[*]}]
set_input_delay -clock [get_clocks clk_fpga_0] -min -add_delay 2.000 [get_ports href]
set_input_delay -clock [get_clocks clk_fpga_0] -max -add_delay 3.000 [get_ports href]
set_input_delay -clock [get_clocks clk_fpga_0] -min -add_delay 2.000 [get_ports pclk]
set_input_delay -clock [get_clocks clk_fpga_0] -max -add_delay 3.000 [get_ports pclk]
set_input_delay -clock [get_clocks VIRTUAL_ov7670_vram_sys_i/OV7670_camera_hs_0/inst/pclk_s] -min -add_delay 2.000 [get_ports vsync]
set_input_delay -clock [get_clocks VIRTUAL_ov7670_vram_sys_i/OV7670_camera_hs_0/inst/pclk_s] -max -add_delay 3.000 [get_ports vsync]
set_output_delay -clock [get_clocks VIRTUAL_clk25_ov7670_vram_sys_clk_wiz_0_0] -min -add_delay -1.000 [get_ports {vo_b_data[*]}]
set_output_delay -clock [get_clocks VIRTUAL_clk25_ov7670_vram_sys_clk_wiz_0_0] -max -add_delay 3.000 [get_ports {vo_b_data[*]}]
set_output_delay -clock [get_clocks VIRTUAL_clk25_ov7670_vram_sys_clk_wiz_0_0] -min -add_delay -1.000 [get_ports {vo_g_data[*]}]
set_output_delay -clock [get_clocks VIRTUAL_clk25_ov7670_vram_sys_clk_wiz_0_0] -max -add_delay 3.000 [get_ports {vo_g_data[*]}]
set_output_delay -clock [get_clocks VIRTUAL_clk25_ov7670_vram_sys_clk_wiz_0_0] -min -add_delay -1.000 [get_ports {vo_r_data[*]}]
set_output_delay -clock [get_clocks VIRTUAL_clk25_ov7670_vram_sys_clk_wiz_0_0] -max -add_delay 3.000 [get_ports {vo_r_data[*]}]
set_output_delay -clock [get_clocks VIRTUAL_clk25_ov7670_vram_sys_clk_wiz_0_0] -min -add_delay -1.000 [get_ports vo_hsync]
set_output_delay -clock [get_clocks VIRTUAL_clk25_ov7670_vram_sys_clk_wiz_0_0] -max -add_delay 3.000 [get_ports vo_hsync]
set_output_delay -clock [get_clocks VIRTUAL_clk25_ov7670_vram_sys_clk_wiz_0_0] -min -add_delay -1.000 [get_ports vo_vsync]
set_output_delay -clock [get_clocks VIRTUAL_clk25_ov7670_vram_sys_clk_wiz_0_0] -max -add_delay 3.000 [get_ports vo_vsync]

合成・インプリメンテーションを実行すると、Unconstainted Pathがなくなりました。

Timing Summary

Clock Interactionを表示するとまだUnsafeなクロック乗せ変えパスが表示されています。WizardのAsynchronous CDCをチェックして赤がついているクロック間を非同期にするとUnsafeの表示を消すことができるのですが、先に示したように、Wizardが生成する制約エントリがうまく認識されないのでこのままとしています。 

Constraints Wizard clock interaction

制約条件を設定することによって、タイミング条件はかなり改善されたようです。入力側の信号がFPGAのFCLKに同期しているわけではないため(実態はカメラ側のPCLKに同期)、本当にこれでよいのかはまだよくわかっていないのですが。

結果

制約条件を加えて作成したBitstreamを使ってカメラを立ち上げると、以前に比べて画質がかなり向上しました。制約条件を入れる前は画像にジャギーが目立っていたのですが、制約条件を設定した後はジャギーがなくなりました。

<制約条件設定前の画像>

Constraints Wizard before

<制約条件設定後の画像>

Constraints Wizard after

制約条件が未設定の状態では回路が正しく動いていなかったことが分かりました。FPGAを使った回路の設計では、制約条件の設定やタイミング・クロージャーは必須事項なのだとよく分かりました。

参考資料

« ZYBOでOV7670カメラモジュールのVGA画像を表示する | トップページ | PYNQ-Z1のOverlay読み込みとPythonからのFPGA PLの制御 »

FPGA」カテゴリの記事

ZYBO」カテゴリの記事

コメント

この記事へのコメントは終了しました。

2018年10月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
無料ブログはココログ