FC2カウンター FPGAの部屋 Constraints Editor

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

FPGAの部屋

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

ISE11.3のConstrants Editorの使い方3

ISE11.3のConstrants Editorの使い方2”の続き

今度はOutputのタイミング制約をしていこう。左のConstraint TypeからOutputsを選択する。そうすると、Unconstrained Input Ports に各入力ポートが出てくるので、とりあえず、その中からcam_clk をダブルクリックして、制約を追加しよう。cam_clk は、ODDR2で出力する予定のCMOSカメラ用のクロックなので、なるようにしかならないのだが、一応どのくらいのディレイで出ている見るために、RISING, FALLING両エッジで10ns 程度入れておくことにする。
Constraints_Editor_15_091002.png

Create Clock to Pad (OFFSET OUT) ダイアログが開く。左上のClock pad net and period をDDRのラジオボタンをクリックした(DDRレジスタで出力するため)。Output clock pad net: をclk に変更、Rising edge constraintsのExternal clock to pad (offset out): に10ns、Fa edge constraintsのExternal clock to pad (offset out): に10ns を設定した。
Constraints_Editor_16_091002.png

これでOKボタンをクリックする。DDRなので、RISINGとFALLINGの2つのエントリが、Constraints EditorのCreate Timing Constraints for Output (OFFSET OUT)に入った。
Constraints_Editor_17_091002.png

次に、dac_blue<0> のタイミング制約を作成する。同様にUnconstrained Output Portsからdac_blue<0>をダブルクリックすると、Create Clock to Pad (OFFSET OUT) ダイアログが開く。
DAC(ADV7125)のデータシートの5ページ目から、データのセットアップ時間が0.2ns、ホールド時間が1.5ns ということが分かった。よって、Rising edge constraintsのExternal clock to pad (offset out): に41.66 - 0.2 - 0.8(配線遅延分)= 40.66 nsとした。ホールド時間は指定できないが、そのくらいは大丈夫だと思う。
Constraints_Editor_18_091002.png

SRAM関係は非同期なので、クロックからの出力時間は関係ないが、そろっていないとまずいので、とりあえず、Rising edge constraintsのExternal clock to pad (offset out): を 10ns としておく。
Constraints_Editor_19_091002.png

あとは例によって、テキストエディタでバスの制約はコピーした。結局、出力のタイミング制約は下のようになった。

NET "cam_clk" OFFSET = OUT 10 ns AFTER "clk" RISING;
NET "cam_clk" OFFSET = OUT 10 ns AFTER "clk" FALLING;
NET "dac_blue<0>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<1>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<2>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<3>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<4>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<5>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<6>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<7>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<0>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<1>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<2>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<3>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<4>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<5>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<6>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<7>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<0>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<1>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<2>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<3>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<4>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<5>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<6>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<7>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "mem_addr<0>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<1>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<2>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<3>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<4>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<5>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<6>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<7>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<8>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<9>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<10>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<11>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<12>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<13>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<14>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<15>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<16>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<17>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<0>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<1>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<2>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<3>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<4>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<5>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<6>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<7>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<8>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<9>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<10>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<11>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<12>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<13>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<14>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<15>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "n_mem_lowerB" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "n_mem_upperB" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "n_mem_rd" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "n_mem_we" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "vga_hsync" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "vga_vsync" OFFSET = OUT 10 ns AFTER "cam_pclk";


  1. 2009年10月03日 05:11 |
  2. Constraints Editor
  3. | トラックバック:0
  4. | コメント:0

ISE11.3のConstrants Editorの使い方2

ISE11.3のConstrants Editorの使い方1”の続き。

IOのタイミング制約をやってみることにする。まずはInputを制約する。
左のConstraint TypeからInputsを選択する。そうすると、Unconstrained Input Ports に各入力ポートが出てくるので、とりあえず、その中からcam_href をダブルクリックして、制約を追加しよう。
Constraints_Editor_6_091001.png

そうすると、Create Setup_Time (OFFSETIN) ダイアログが開く。ここではInterface Tyte やData rate Clock edge などを選択するが、この場合はデフォルト値でOKなので、そのままNext > ボタンをクリックして次に進める。
Constraints_Editor_7_091001.png

CMOSイメージセンサOmniVision社のOV7640のマニュアルから、最悪値で行くと、HREFはPCLKの立下りから5nsで有効 (tpHH) になって、PCLKの立下りから0nsで無効 (tpHL) になることが分かる。つまり、クロックの立ち上がりでサンプルする時のセットアップ時間は41.66/2 -5 = 15.83 ns 、HREFが有効な時間は15.83 + 41.66/2 = 36.66 ns であるので、それぞれExternal setup time とData valid duration に値を設定する。
Constraints_Editor_8_091002.png

そして、Finishボタンをクリックすると、Constraints EditorのCreate Timing Constraints for Input (OFFSET IN) にcam_hrefの制約が入る。
Constraints_Editor_9_091002.png

次はcam_vsyncも同様の値を入力する。
次はcam_ydataのタイミング制約を入力する。まずはUnconstrained Input Ports の中のcam_ydata<0>をダブルクリックする。
Constraints_Editor_10_091002.png

そうすると、Create Setup_Time (OFFSETIN) ダイアログが開く。ここではInterface Tyte やData rate Clock edge などを選択するが、この場合はデフォルト値でOKなので、そのままNext > ボタンをクリックして次に進める。(キャプチャ図は省略)
Yデータのクロックの立ち上がりからのセットアップ時間は15 ns 、ホールド時間は8 ns なので、セットアップ時間はそのままだが、有効な時間は34.66 ns 23 nsとなる。
Constraints_Editor_11_091002.png

それで、Finishボタンをクリックする。
Constraints_Editor_12_091002.png

ここまで終了したら、いったんSaveアイコンをクリックして、セーブしてからConstraints Editorを終了する。
CamDispCntrl_SRAM.ucf ファイルを見てみよう。

NET "clk" TNM_NET = clk;
TIMESPEC TS_clk = PERIOD "clk" 20.83 ns HIGH 50%;
NET "cam_pclk" TNM_NET = cam_pclk;
TIMESPEC TS_cam_pclk = PERIOD "cam_pclk" 41.66 ns HIGH 50%;
NET "cam_href" OFFSET = IN 15.83 ns VALID 36.66 ns BEFORE "cam_pclk" RISING;
NET "cam_vsync" OFFSET = IN 15.83 ns VALID 36.66 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<0>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;


上のような制約が追加されている。他のcam_ydataはConstraints Editorから制約しても良いのだが、面倒なので、テキストエディタ(私はPeggyに自作のUCF用の定義ファイルを適用して使っています。”PeggyのUCFファイル用KWDファイル”参照)で制約を複製してしまうのが面倒がなくて良いと思っている(もちろんProject Navigaterから呼び出せる付属のテキストエディタで修正しても良い)。
Constraints_Editor_13_091002.png

もう一度、ProcessesペインのUser Constraints -> Create Timing Constrints をダブルクリックしてConstrinats Editor を起動する。そうすると、Constraints EditorのCreate Timing Constraints for Input (OFFSET IN) にcam_ydataがすべて入っている。
Constraints_Editor_14_091002.png

次は、mem_dataだ。やり方は前と同じなので省略する。SRAMのデータシートによると、アドレスやOE確定から10 ns なので、FPGAからのアドレス出力やOE出力のクロックからの出力時間を10 ns とする。さらにデータが有効になるのはアドレスやOE確定後から10 ns 後となる。と、セットアップ時間は41.66 - 10 - 10 = 21.66 ns となる。余裕がある。データが有効な時間は21.66 + データホールドの最小時間 0 nsなのだが、OEやアドレスの遅延時間の最小値を3 ns と見込んで = 24.66 nsとした。
同様にテキストエディタで複製し、修正したので、最終的なinputの制約は下のようになった。

NET "clk" TNM_NET = clk;
TIMESPEC TS_clk = PERIOD "clk" 20.83 ns HIGH 50%;
NET "cam_pclk" TNM_NET = cam_pclk;
TIMESPEC TS_cam_pclk = PERIOD "cam_pclk" 41.66 ns HIGH 50%;
NET "cam_href" OFFSET = IN 15.83 ns VALID 36.66 ns BEFORE "cam_pclk" RISING;
NET "cam_vsync" OFFSET = IN 15.83 ns VALID 36.66 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<0>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<1>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<2>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<3>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<4>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<5>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<6>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<7>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "mem_data<0>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<1>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<2>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<3>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<4>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<5>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<6>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<7>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<8>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<9>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<10>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<11>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<12>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<13>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<14>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<15>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;



(2009/10/07 修正)
cam_ydataのValid時間を34.66 nsから23 nsに修正しました。

  1. 2009年10月02日 05:45 |
  2. Constraints Editor
  3. | トラックバック:0
  4. | コメント:2

ISE11.3のConstrants Editorの使い方1

CMOSカメラから画像を入力してディスプレイへ出力7”でConstraints Editorの使い方が良くわからなかったので、設定しながら勉強してみることにした。実際は、”Spartan3A Starter KitのDDR2 SDRAMコントローラのバーストテストのインプリメント3(DDR2-300がOK)”で、ISE11.1のConstraints Editorを使っているが、タイミング制約は大半が出来ているときにMAXDEALY制約やMAXSKEW制約を入れるのに使用している。
とりあえず、すべてのタイミング制約(クロックの最大周期、IOのセットアップ時間、クロックからの出力時間)などを消した状態で、ProcessesペインのUser Constraints -> Create Timing Constrints をダブルクリックしてConstrinats Editor を起動する。(Constrinats Editorは、ISEのアクセサリから単体で起動することもできるが、今回のやり方ではProject Navigator上でConstraints Editorを起動してタイミング制約を作成する)

Constaraints EditorはXilinx社のFPGAの制約(ソフトウェア、VBなどでいえばプロパティ)の主にタイミングに関する制約をGUIで書くことができるEditor。タイミング制約は最終的にテキストで書かれた制約として制約ファイル(.ucf) に書かれる。制約の文法については、ISE11の制約ガイドを参照。なお、エリア制約やIOパッドの位置などの配置制約をGUIで書くことができるツールはPlanAheadである(ISE11の場合)。
いずれの制約も制約ファイル(.ucf)を、テキストエディタ等で直接編集することが可能である。


Constraints_Editor_1_091001.png

最初にConstraints Editor (Timing Constraits) が起動すると下のような表示になる。
Constraints_Editor_2_091001.png

clkとcam_clkがUnconstrained Clocks のところに表示されている。まだ制約をかけていないクロックドメインということのようだ。
ちなみに、Timing Constraintsの画面にするとProject Navigatorウインドウの横幅のリサイズが効かない縦のリサイズは効くんだけど。。。バグかな?
さて、とりあえずclkのタイミング制約をかけてみる。Unconstrained Clocks のところに表示されているclkをダブルクリックするとClock Periodダイアログが表示される。今回はごく標準的な設定で良いので、Clock signal definition のSpecify time のTime:を48MHzの周期20.83ns に書き換えた。Rising duty cycle は50% で良いので、そのままとした。下の方のInput jitterは値がわからにので入れない。(それほどシビアな回路でもない)
Constraints_Editor_3_091001.png

これで、OKボタンをクリックすると、clkが上のCreate Timing Constraints for Clock Domain (PERIOD) に表示される。
Constraints_Editor_4_091001.png

次にcam_clkも同様に行う。こちらの周波数は24MHzなので、Clock signal definition のSpecify time のTime:を 41.66ns に設定した。
Constraints_Editor_5_091001.png

これでUnconstrained Clocksはなにもなくなった。
次はIOのタイミング制約をやってみることにする。まずはInputから。
  1. 2009年10月01日 05:58 |
  2. Constraints Editor
  3. | トラックバック:0
  4. | コメント:0