コード中に制約を書くときの注意点 のバックアップ差分(No.1)
更新- 追加された行はこの色です。
- 削除された行はこの色です。
[[公開メモ]] #contents * コード中に制約を埋め込む [#s40b8ab3] 次のコードは [[非同期信号を扱うための危ういVerilogライブラリ>電気回路/HDL/非同期信号を扱うための危ういVerilogライブラリ#非同期信号を2段FFで受ける]] で紹介している、非同期信号を同期化するためのコードです。 LANG:verilog module double_ff #( parameter INIT = 1'b0 ) ( (* TIG="TRUE" *) input wire idata, input wire oclk, output wire odata ); wire temp; (* IOB="FALSE", RLOC="X0Y0", ASYNC_REG="TRUE" *) FDRSE #( .INIT(INIT) // Initial value of register (1'b0 or 1'b1) ) temp0 ( .Q(temp), // Data output .C(oclk), // Clock input .CE(1'b1), // Clock enable input .D(idata), // Data input .R(1'b0), // Synchronous reset input .S(1'b0) // Synchronous set input ); (* IOB="FALSE", RLOC="X0Y0" *) FDRSE #( .INIT(INIT) // Initial value of register (1'b0 or 1'b1) ) temp1 ( .Q(odata), // Data output .C(oclk), // Clock input .CE(1'b1), // Clock enable input .D(temp), // Data input .R(1'b0), // Synchronous reset input .S(1'b0) // Synchronous set input ); endmodule このモジュールは1つのプロジェクト中で何十回、何百回も使うことになるため、 上記のように TIG や IOB, ASYNC_REG, RLOC といった制約をコード中に埋め込めれば 大きな助けになります。 そうでなければ、何百もの double_ff のインスタンスに対応する個別の制約を .ucf ファイルに別途記述しなければならないからです。 上記制約は次の意味を持っています。 - idata から temp0 へのパスは遅延解析が必要ないため idata に TIG を付けています - temp0 や temp1 が IOB に入らないように IOB を付けています - temp0 は非同期信号を受け取る事が分かっているので ASYNC_REG を付けています - temp0 と temp1 とが同じスライスに入るように RLOC を付けています この書き方は ISE コードエディタの Language Templates の記述をほぼ踏襲しているのですが、 そのままつかうにはいくつか問題がありそうで、いろいろ調べてみました。 * 異なるパラメータでインスタンス化する [#if684495] 問題をはっきりさせるため、下記のあまり意味はないですがシンプルな例で見てみます。 LANG:verilog module main1 ( input clk_125MHz_in, input idata, output odata ); DCM_SP #( .CLKIN_PERIOD(8.0), // Specify period of input clock .CLK_FEEDBACK("1X") // Specify clock feedback of NONE, 1X or 2X ) DCM_SP_inst ( .CLK0(clk_125MHz), // 0 degree DCM CLK output .CLK90(clk_125MHz90), // 90 degree DCM CLK output .CLKFB(clk_125MHz), // DCM clock feedback .CLKIN(clk_125MHz_in) // Clock input (from IBUFG, BUFG or DCM) ); double_ff double_ff0 ( .idata(idata), .oclk(clk_125MHz), .odata(clk0_idata) ); double_ff double_ff90 ( .idata(clk0_idata), .oclk(clk_125MHz90), .odata(clk90_idata) ); assign odata = clk90_idata; endmodule 対応する ucf ファイル NET "clk_125MHz_in" TNM_NET = "clk_125MHz_in"; TIMESPEC TS_clk_125MHz_in = PERIOD "clk_125MHz_in" 8 ns HIGH 50 %; これは、idata という非同期入力を clk_125MHz_in に同期化し、 さらにその信号を clk_125MHz_in と 90 度ずれた位相を持つクロックに同期化して、 出力します。 入力クロック clk_125MHz_in タイミング制約が掛かっているので、 clk_125MHz, clk_125MHz90 も 125MHz で動作するよう制約が掛かります。 ** PERIOD 制約について [#g1b133fc] この記事の趣旨から言えば、クロックに対する制約も .ucf ファイルに書くのではなく、 LANG:verilog module main( (* PERIOD="125MHz" *) input clk_125MHz_in, input idata, output odata ); のように書いてしまえばよいはずなのですが、これだと、インプリメント中のメッセージで WARNING:Xst:1577 - Converting constraint on signal clk_125MHz_in: 'PERIOD=125MHz' to XCF style constraint NET clk_125MHz_in PERIOD = 125.000000 MHz HIGH 50 % となって、一見うまく行っているように見えるものの、 WARNING:ConstraintSystem:3 - Constraint <TIMESPEC TS_clk_125MHz = PERIOD "clk_125MHz" TS_clk_125MHz_in HIGH 50%>: This constraint will be ignored because the relative clock constraint named 'TS_clk_125MHz_in' was not found. WARNING:ConstraintSystem:3 - Constraint <TIMESPEC TS_clk_125MHz90 = PERIOD "clk_125MHz90" TS_clk_125MHz_in PHASE 2 ns HIGH 50%>: This constraint will be ignored because the relative clock constraint named 'TS_clk_125MHz_in' was not found. となって、正しく制約が掛かりませんでした。 実際 .pcf にはクロック周期制約の記載がなく、どうなっているのかまだ不明です。 * main1 に対する .pcf ファイル [#vad2cbe9] 上記コードをインプリメントすると、.pcf ファイルは次のようになりました。 SCHEMATIC START; TIMEGRP clk_125MHz90 = BEL "double_ff90/double_ff_temp1" BEL "double_ff90/double_ff_temp0"; TIMEGRP clk_125MHz90_0 = BEL "double_ff90/double_ff_temp1" BEL "double_ff90/double_ff_temp0"; TIMEGRP clk_125MHz = BEL "double_ff0/double_ff_temp1" BEL "double_ff0/double_ff_temp0"; TIMEGRP clk_125MHz_0 = BEL "double_ff0/double_ff_temp1" BEL "double_ff0/double_ff_temp0"; PIN DCM_SP_inst_pins<3> = BEL "DCM_SP_inst" PINNAME CLKIN; TIMEGRP clk_125MHz_in = PIN "DCM_SP_inst_pins<3>"; TS_clk_125MHz_in = PERIOD TIMEGRP "clk_125MHz_in" 8 ns HIGH 50%; TS_clk_125MHz = PERIOD TIMEGRP "clk_125MHz" TS_clk_125MHz_in HIGH 50%; TS_clk_125MHz90 = PERIOD TIMEGRP "clk_125MHz90" TS_clk_125MHz_in PHASE 2 ns HIGH 50%; TS_clk_125MHz_0 = PERIOD TIMEGRP "clk_125MHz_0" TS_clk_125MHz_in HIGH 50%; TS_clk_125MHz90_0 = PERIOD TIMEGRP "clk_125MHz90_0" TS_clk_125MHz_in PHASE 2 ns HIGH 50%; PIN "idata_IBUF_pins<1>" = BEL "idata_IBUF" PINNAME OUT; PIN "double_ff0/double_ff_temp1_pins<2>" = BEL "double_ff0/double_ff_temp1" PINNAME Q; PIN "idata_IBUF_pins<1>" TIG; PIN "double_ff0/double_ff_temp1_pins<2>" TIG; SCHEMATIC END; クロックに対する記述を除くと、 PIN "idata_IBUF_pins<1>" = BEL "idata_IBUF" PINNAME OUT; PIN "double_ff0/double_ff_temp1_pins<2>" = BEL "double_ff0/double_ff_temp1" PINNAME Q; PIN "idata_IBUF_pins<1>" TIG; PIN "double_ff0/double_ff_temp1_pins<2>" TIG; の部分が double_ff 関連の制約です。 * TIG は出力ピンまで遡ってかかる [#wd567aae] .pcf の記述から、double_ff の入力ピンに記述した TIG 制約は、 そこに接続された出力ピンまで遡って付いています。 これはかなり困ったことで、その出力ピンに double_ff 以外のモジュールが接続されていると、 そちらへのパスも遅延解析から除かれてしまうことになります。 &attachref;
Counter: 19845 (from 2010/06/03),
today: 4,
yesterday: 0