FC2カウンター FPGAの部屋 制約

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

FPGAの部屋

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

set_clock_groups -asynchronous 制約

HDMI入力XGA表示回路3(インプリメント)”で、BUFR_pixel_clk_io/O と clk_fpga_0 の 2 つのクロック間の依存関係を set_false_path で無効にしていたが、set_clock_groups -asynchronous の方が良いという情報があった。

Vivado Design Suite ユーザー ガイド 制約の使用 UG903 (v2015.1) 2015 年 4 月 1 日”の 41 ページを見るとTiming Constraints Wizard の Asynchronous Clock Domain Crossing の図があって、その下に、以下のように書いてある。

どちらの方向のタイミングも無視するのが安全な場合 - set_clock_groups (-asynchronous)
一方向のパスを無視するのが安全な場合 - set_false_path


これを見ると、set_false_path でも、set_clock_groups (-asynchronous) でも同じ気がするが、”HDMI入力XGA表示回路3(インプリメント)”で設定した set_false_path を set_clock_groups -asynchronous に変更した。

やり方を示す。なお、set_false_path をコメントアウトした状態にしてある。

Implemented Design を開いて、Edit Timing Constraints をクリックする。

Timing Constraints タブが開く。

Clocks -> Set Clock Groups をクリックする。

Double click to create a Set Clock Groups constraint をダブルクリックする。
ZYBO_1_XGA_test_34_151217.png

Set Clock Groups ダイアログが立ち上がる。

Group name を pixel_clk2clk_fpga_0 に設定して、Group 1 に BUFR_pixel_clk_io/O を、Group 2 に clk_fpga_0 を指定して、OKボタンをクリックする。
ZYBO_1_XGA_test_35_151217.png

制約ファイルに、set_clock_groups (-asynchronous) 制約が設定された。

set_clock_groups -name pixel_clk2clk_fpga_0 -asynchronous -group [get_clocks [list [get_clocks -of_objects [get_pins ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/dvi_disp_i/BUFR_pixel_clk_io/O]]]] -group [get_clocks clk_fpga_0]


制約をセーブして、再度、論理合成、インプリメント、ビットストリームの生成を行って成功した。制約は問題無いようだ。
  1. 2015年12月19日 18:45 |
  2. 制約
  3. | トラックバック:0
  4. | コメント:0

BUFR でクロックを分周する場合は制約を追加する必要がある(ビットマップ・ディスプレイ・コントローラ IP のHDMI 出力)

Zynq のビットマップ・ディスプレイ・コントローラのHDMI 出力では、VGA, SVGAは安定して出力できるが、XGA以上になると時々プチプチ切れる現象が続いていた。(”ZYBOにビットマップ・ディスプレイ・コントローラを追加する1(仕様)”参照)

並列ステレオカメラによる距離の測定5(ZYBO 0 のハードウェア4)”でもHDMI 出力のXGA 画像が時々消えてしまっていた。

Digilent 社のDigilentInc/vivado-library を Download ZIP して見ていた時に、ip\rgb2dvi_v1_2\src を見ていたら制約のXDCファイルがある。制約を見るとHDMI の周波数がピクセルクロックの5倍のSerDes 用クロックは、ピクセルクロックのクロック周波数の 5 倍の周波数であるという記述だった。

もしかしてこの記述が重要なのか?と思い、自分のMMCM の制約として付けてみることにした。取りあえずは、ビットマップ・ディスプレイ・コントローラ IPの制約ではなく、プロジェクト全体への制約として付加することにする。

MMCM回りのVHDL記述を下に示す。

MMCM_BASE_PIXEL : MMCME2_BASE generic map (
BANDWIDTH => "OPTIMIZED",
    CLKOUT4_CASCADE     => FALSE,
    STARTUP_WAIT        => FALSE,
    CLKFBOUT_MULT_F => MMCM_CLKFBOUT_MULT,
CLKIN1_PERIOD => MMCM_CLKIN_PERIOD,
CLKOUT0_DIVIDE_F => MMCM_CLKOUT0_DIVIDE,
DIVCLK_DIVIDE => 1
) port map (
CLKFBOUT => mmc_fb_out,
CLKOUT0 => pixel_clkx5,
LOCKED => mmcm_locked,
CLKFBIN => mmc_fb_in,
CLKIN1 => clk25,
PWRDWN => '0',
RST => '0'
);
mmcm_locked_n <= not mmcm_locked;
mmc_fb_in <= mmc_fb_out;
-- BUF_FB : BUFG port map(
-- I => mmc_fb_out,
-- O => mmc_fb_in
-- );
BUFIO_pixel_clkx5 : BUFIO port map (
O => pclkx5_buf,
I => pixel_clkx5
);
BUFR_pixel_clk_io : BUFR generic map(
BUFR_DIVIDE => "5",
SIM_DEVICE => "7SERIES"
) port map (
O => pclk_buf,
CE  => '1',
CLR => mmcm_locked_n,
I => pixel_clkx5
);
CLK_OUT_BUFG : bufg port map (
O => pclk_buf_out,
I => pclk_buf
);
pclk_out <= pclk_buf_out;
pclk_locked <= mmcm_locked;


上のVHDL ソースコードで pclkx5_buf がOSERDESE2 用の出力データシフト用クロックだ。OSERDESE2 のモードはDDR となっている。ピクセルクロックはBUFR で 5 分周されたpclk_buf_out だ。(BUFRに関しては、”AR# 465057 シリーズ FPGA デザイン アシスタント - クロック バッファーの使用”を参照)

そこで、Flow Navigator のImplementation -> Implemented Desgin をクリックして、Implemented Desgin 画面を起動した。

Flow Navigator のImplementation -> Implemented Desgin -> Edit Timing Constraints をクリックしてタイミング制約を編集した。
もうすでに入っているが、Create Generate Clock に pclkx5_buf クロックを元に1/5 してpixclk を作っているという制約が入っている。
StereoCam_48_151121.png

StereoCam_49_151121.png

制約の記述を示す。

create_generated_clock -source [get_pins ZYBO_0_i/bitmap_disp_cntrler_axi_master_1/inst/dvi_disp_i/hdmi_tx_i/pclkx5_buf] -divide_by 5 [get_pins ZYBO_0_i/bitmap_disp_cntrler_axi_master_0/inst/dvi_disp_i/pixclk]


これで、”並列ステレオカメラによる距離の測定5(ZYBO 0 のハードウェア4)”をもう一度、論理合成、インプリメント、ビットストリームの生成を行ったところ、XGA 解像度のHMDI 出力が安定した。

通常は、MMCMやPLL で異なる周波数のクロックを出力しても自動的に新しいクロックの制約を自動生成してくれると思うのだが、BUFR に関してはやってくれないのかもしれない?
ビットマップ・ディスプレイ・コントローラ IP の制約として一緒にIP したほうが良いと思う。
  1. 2015年11月21日 05:51 |
  2. 制約
  3. | トラックバック:0
  4. | コメント:0

HSYNCとVSYNCをIOBレジスタに入れる

”ZedBoardでHDMI出力13(HDMIに出力できた)”のプロジェクトをFPGA Editor でみたところ、hdmi_hsync, hdmi_vsync, vga_hsync, vga_vsync もデータもIOBのレジスタを使用していなかった。

全体像を説明するために、話をHSYNCやVSYNCに絞って、そのブロック図を図1 に示す。
ZedBoard_HDMI_42_121129.png
図1 HSYNC, VSYNC出力ブロック図

bitmap_disp_cntrler_axi_master.v がビットマップ・ディスプレイ・コントローラのトップだ。その下に、bitmap_disp_engine.v とconv_hdmi_out.v がある。bitmap_disp_engine.v にはTiming Generatorがあって、HSYNCやVSYNCを生成している。それをFFを介してbitmap_disp_cntrler_axi_master.v に出力して、それをconv_hdmi_out.v に入力する。conv_hdmi_out.v では、YCbCr4:2:2 変換を行うために2クロック分遅延するので、その分をHSYNC, VSYNCも遅延させるために2段のFFを通している。bitmap_disp_engine.v のHSYNC, VSYNCは、conv_hdmi_out.v に渡しているので、このままではIOBレジスタを使用できない。その為、もう1段FFを介してFPGA外に出力している。

最初に、PlanAheadでFlow navigator のImplementation のImplementation Settings をクリックして、Mapのオプションを見た。none になっていたので、oに変更した。(グローバル・オプションで出力の最後のFFをIOBレジスタにマップするオプション)
ZedBoard_HDMI_43_121129.png

これでインプリメントしてみたところ、HDMI関連はIOBレジスタを使用したが、vga_hsync, vga_vsync はIOBレジスタを使えていなかった。

次に、UCFファイルで、vga_hsync, vga_vsync, hdmi_hsync, hdmi_vsync にIOB = FORCE 制約を試してみたが、なぜか効かなかった?

そこで、Verilog HDLソースファイルのポート宣言に(* IOB = "FORCE" *)を追加した。

(* IOB = "FORCE" *) output reg vga_hsync,
(* IOB = "FORCE" *) output reg vga_vsync,
(* IOB = "FORCE" *) output wire hdmi_vsync,
(* IOB = "FORCE" *) output wire hdmi_hsync,


これでやっと、vga_hsync, vga_vsyncがIOBレジスタに入らないとのエラーが出るようになった。どうやら、図1のFF2とFF3が統合されてしまっているようだ。これを防ぐためには、Synthhesis オプションの equivalent_register_removal をyes から no にすれば良いと思うのだが、全体にかかってしまうためやらない。

図1のFF3, FF4にS属性(S制約)を掛けてFFをキープした。

(*S="TRUE"*) reg hsyncx_d1, hsyncx_d2;
(*S="TRUE"*) reg vsyncx_d1, vsyncx_d2;


これでも、やはり、vga_hsync, vga_vsyncがIOBレジスタに入らないとのエラーが出る。

FF2にS属性(S制約)を掛ければ良いのだが、すでにIOB = "FORCE"制約を掛けているので、2つ制約が書けるかどうか分からなかった。(1回、やってみるのに時間が掛かるんです)試しに、FF1にS属性(S制約)を掛けてみた。

(*S="TRUE"*) output reg hsyncx,
(*S="TRUE"*) output reg vsyncx,


これでインプリメントしてみたところ、うまく、全部のポートでIOBレジスタを使うことができるようになった。
ZedBoard_HDMI_44_121129.png

ZedBoard_HDMI_45_121129.png

本当は出力ポートのvga_hsync, vga_vsync をreg で宣言してFFにするよりも、1つ前にノードをreg で宣言して、FF記述をして、そこをS属性(S制約)を掛ける。そして、そこから出力ポートに結んで、そこに、 IOB = "FORCE" 制約を掛けたほうが良いと思われる。
  1. 2012年11月29日 05:51 |
  2. 制約
  3. | トラックバック:0
  4. | コメント:0