Xilinx ISE のメッセージフィルタ の履歴(No.6)
更新メッセージフィルタ†
ISE で論理合成する時、 ちょっと大きな回路だと無数の警告が表示されてしまうために、 本当に必要な警告を見落としてしまうことが多いです。
それを解決するために提供されているのがメッセージフィルタという機能。
特定の警告を表示されないように指定できます。
使い方は、Design Summary のページから Erros and Warning で該当メッセージを右クリックし、"Filter All Instance of This Message" あるいは "Filter This Instance Only" を選びます。
上記2つの項目のどちらもメニューのアクセラレータキーが "F" になっていて、 キーボードで選択できないなど、手抜き加減が見えますが、、、
それ以外にも以下のように、 かなり使い物にならないできばえであるのが残念なところです。
青文字で表示されるメッセージにフィルタをかけるには†
青文字で表示されるメッセージは右クリックすると発生行に飛んでしまいます。
仕方がないので、カーソルで選択して、 キーボードのコンテキストメニューキーでメニューを表示してフィルタを掛けます。
バグに近い仕様ですね。(ISE 12.2)
メッセージエディタが使いにくすぎる†
一旦追加したフィルタを無効化したり、削除したりするために メッセージエディタと言うのを使います。
ただ、この機能はGUIが貧弱すぎて、まともに使うのがつらいです。
多くのフィルタを追加してある状況では "Edit Message Filters..." から フィルタの一覧を表示するだけでも数十秒以上待たされますし、
フィルタを無効化したり、削除したりするのに複数のフィルタを一度に 選んで消すことができないため、何十回もクリックを繰り返す羽目になります?! (ISE 12.2)
あまりにひどい。
メッセージフィルタの設定ファイル†
メッセージフィルタの設定は、以下のファイルに XML 形式で書かれています。
- ISE 11.X まではプロジェクトファイルと同じフォルダにある filter.filter
- ISE 12.1 からは iseconfig の下の filter.filter
多数のフィルタを一度に消したければ、メッセージエディタを使わずに これをテキストエディタで開いて編集するのが良さそうです。
慎重にやらないとファイルを壊してしまうことになりますが。
メッセージフィルタの設定項目†
例として、PicoBlaze を使うだけで数十個表示される
Xst:616 - Invalid property "XC_PROPS INIT": Did not attach to data_srl_0.
というメッセージに対して This Instance Only でフィルタを設定してみると、 設定ファイルには
LANG:xml <filter task="xst" file="Xst" num="616" type="warning"> <arg index="1">XC_PROPS</arg> <arg index="2">INIT</arg> <arg index="3">data_srl_0</arg> </filter>
という項目が追加されました。
フィルタに発生箇所が含まれない場合がある†
上記内容から、フィルタにはファイル名などの情報が含まれていない場合があり、その場合にはたまたま変数名がかぶってしまうと、別の部分にかけたフィルタが予期しない部位の警告を無効化してしまう可能性がある ことが分かります。
メッセージに発生位置が表示されていない警告をフィルタする場合には このことに注意しないと、予期できないエラーに悩まされる可能性があります。
条件を緩和してみる†
同じことを All Instances of This Message としてやると、
LANG:xml <filter task="xst" file="Xst" num="616" type="warning"></filter>
となりました。
そこで、上記フィルタを編集して
LANG:xml <filter task="xst" file="Xst" num="616" type="warning"> <arg index="1">XC_PROPS</arg> <arg index="2">INIT</arg> </filter>
としてみたところ、変数名に依らず、以下の形のメッセージを全てフィルタすることができました。
Xst:616 - Invalid property "XC_PROPS INIT": Did not attach to ????
数十のメッセージを消すのに数十のフィルタを追加してしまうと 手抜きのGUIのせいで大変なことになってしまいますから、 このように条件の緩いフィルタ1つで多くのメッセージを 抑制できるのは便利ですね。
ファイル名が表示されたメッセージでは行が変わるとフィルタが効かない†
Xst:2591 - "kcpsm3/kcpsm3.v" line 402: attribute on instance <INIT> overrides generic/parameter on entity. It is possible that simulator will not take this attribute into account.
に対して作成したフィルタでは、
LANG:xml <filter task="xst" file="Xst" num="2591" type="warning"> <arg index="1">"kcpsm3/kcpsm3.v" line 402:</arg> <arg index="2">attribute on instance</arg> <arg index="3">INIT</arg> <arg index="4">generic/parameter on entity</arg> </filter>
となりました。発生場所が引数の1番目に入っています。
引数に行番号が入ってしまいますので、 ソースコードを編集して行番号がずれてしまうとフィルタが効かなくなってしまう という恐ろしい仕様であることが分かります。
一旦フィルタしたはずのメッセージが、ソースの編集後に再度表示されるため、 またフィルタをかける、という繰り返しにより、1つのメッセージのもマッチしない、 まったく意味のないフィルタ定義が際限なく増えてしまうことになります。
ファイル名と行番号が別の引数になっていてくれれば、 行番号部分の指定を削ったフィルタにしてやれば事が済むのですが、 これではどうしようもないですね。。。
仕様がよく錬られていないことが仇になっています。
せめて、 Rebuild All の際に1回もマッチしなかったフィルタを表示して消せる機能 が欲しいところです。
できれば、削除ではなく自動で行番号を調整し直してくれれば言うことないのですが。
ファイル名と行番号とが別のメッセージもある?†
Xst:2546 - "utility/bmem.v" line 46: reading initialization file "vga/obj/svga16color_screen00.mem".
については、
LANG:xml <filter task="xst" file="Xst" num="2546" type="info"> <arg index="1">utility/bmem.v</arg> <arg index="2">46</arg> <arg index="3">vga/obj/svga16color_screen00.mem</arg> </filter>
となって、ファイル名と行番号とが別になっているので、 行番号部分を除いて条件を緩和して、次のようにしておけば ソースコードを編集してもフィルタが無効になることはないですね。
LANG:xml <filter task="xst" file="Xst" num="2546" type="info"> <arg index="1">utility/bmem.v</arg> <arg index="3">vga/obj/svga16color_screen00.mem</arg> </filter>
メッセージリストで青色で表示されていて、 クリックでソース行に飛べる物だけがこの形で正しく情報を含んでいるようです。
本当はすべてこの形にしたかったのに、 まだ手が回っていないと言うことなのかもしれませんね。
条件を緩和したフィルタが勝手に変更されてしまう†
上記のように条件を緩和したフィルタは便利に使えるのですが、 GUIから新しいフィルタを追加すると勝手に書き換えられてしまうようです(泣
LANG:xml <filter task="xst" file="Xst" num="2546" type="info"> <arg index="1">utility/bmem.v</arg> <arg index="2">vga/obj/svga16color_screen00.mem</arg> </filter>
飛んでいた番号が連番に戻されてしまいました↑
読み込んだ当初、フィルタ自体は正しく動作するので、 フィルタ定義を書き出す部分で index の値を見ずに、 先頭から 1, 2, 3, ... と番号を振ってしまっているようです。
うーむ、どうしろっていうんだか・・・
ファイル名だけを指定したフィルタは作れないみたい†
<filter> の中の num="2546" を消してしまって、
LANG:xml <filter task="xst" file="Xst" type="info"> <arg index="1">utility/bmem.v</arg> </filter>
とすれば、このファイルの中の全ての info メッセージを抑制できるのかと思ったのですが、 num の指定のない <filter> は単に無視されてしまうようでした。
kcpsm3.v のように、 すでに実績のあるソースからのメッセージをすべて抑制するような フィルタが定義できると便利だと思ったのですが、だめでした。
結論†
現状では、メッセージフィルタを使っても、警告メッセージをまともに見られるようにするのは Xilinx ISE を標準的な方法で使っている限り難しいみたいですね。
皆さんどうしているんでしょう????
やはり、フィルターのような姑息な(?)手段ではなく、 C の #pragma のような機能を使って、ソースコード中の特定の範囲で、 特定の警告メッセージを抑制できるようにして欲しいところです。
まあ、メッセージフィルタはメッセージフィルタで、 テストコードなどのために「一時的に」使うのには便利なので、 複数のフィルタをグループ分けして、一気に有効・無効を切り替えたり、 削除したりできるといいですね。
自分で何とかするのであれば、
- フィルタ定義ファイルの編集 GUI を作る
- フィルタ定義ファイルをスクリプトを使って自動生成する
あたりが考えられるのですが、、、今一気乗りがしません。
Xilinx さん頑張って!!!
もがき中†
以下のようなファイルを目的別にいくつか手動で管理しつつ、 make を使って filter.filter ファイルを自動生成してみています。
もう少し楽な方法が無いか考え中です。
common.filter.src
LANG:xml <!-- Xst:3039 - The RAM <Mrom__varindex0000> will be implemented as BLOCK RAM --> <filter task="xst" file="Xst" num="3039" type="info"> <arg index="1">Mrom__varindex0000</arg> </filter> <!-- Xst:2591 - "kcpsm3/kcpsm3.v" line 402: attribute on instance <INIT> overrides generic/parameter on entity. It is possible that simulator will not take this attribute into account. --> <filter task="xst" file="Xst" num="2591" type="warning"> <!-- arg index="1">"kcpsm3/kcpsm3.v" line 402:</arg --> <arg index="2">attribute on instance</arg> <arg index="3">INIT</arg> <arg index="4">generic/parameter on entity</arg> </filter> <!-- Xst:616 - Invalid property "XC_PROPS INIT": Did not attach to count_lut_4. --> <filter task="xst" file="Xst" num="616" type="warning"> <arg index="1">XC_PROPS</arg> <arg index="2">INIT</arg> <!-- arg index="3">count_lut_4</arg --> </filter> <!-- Xst:3044 - The ROM <Mrom__varindex0000> will be implemented as a read-only BLOCK RAM, absorbing the register: <instruction>. --> <filter task="xst" file="Xst" num="3044" type="info"> <arg index="1">Mrom__varindex0000</arg> <!-- arg index="2">instruction</arg --> </filter> <!-- Xst:2040 - Unit trimac_control: 16 multi-source signals are replaced by logic (pull-up yes): --> <filter task="xst" file="Xst" num="2040" type="warning"> <!-- arg index="1">trimac_control</arg --> <!-- arg index="2">16</arg --> <!-- arg index="3">yes</arg --> </filter>
新しいフィルタを追加するときには、 メッセージ番号をメモっておいて、 追加した filter.filter の中で検索することで、 何とか追加行を見つけています。
やっぱり役に立たないかも†
メッセージに発生箇所が含まれないというのは思った以上にクリティカルで、 フィルタ機能はほとんど役に立たない感じがしてきました。
例えば、
Xst:647 - Input <async_rst> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
というメッセージには、発生箇所が含まれません。 Console をたどってみると、このメッセージは
Synthesizing Unit <trimac_rx_mem>. Related source file is "trimac/trimac_rx_mem.v". (ここに表示される) Unit <trimac_rx_mem> synthesized.
のように囲まれているので、trimac_rx_mem モジュールに関するメッセージであることが やっと分かるのですが、非常に不親切、と以前から思っていました。
で、もっとまずいのは、 たまたまそのモジュールについては async_rst 意図的に繋いでいなかったからと このメッセージをフィルターしてしまうと、
LANG:xml <filter task="xst" file="Xst" num="647" type="warning"> <arg index="1">async_rst</arg> </filter>
というフィルターができてしまいます。
すると他のモジュールでうっかり async_rst という名前の線をつなぎ忘れていても それを警告するメッセージが現れなくなってしまいます。
今まで知らないで使っていたので、冷や汗たらたら出てきました。
これはクリティカルすぎます。
他にも、
Xst:647 - Input <async_rst> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved. Xst:646 - Signal <idata_empty1> is assigned but never used. This unconnected signal will be trimmed during the optimization process. Xst:1781 - Signal <instructions> is used but never assigned. Tied to default value. Xst:653 - Signal <GSR_in> is used but never assigned. This sourceless signal will be automatically connected to value 0. Xst:1767 - HDL ADVISOR - Resource sharing has identified that some arithmetic operations in this design can share the same physical resources for reduced device utilization. For improved clock frequency you may try to disable resource sharing. Xst:1426 - The value init of the FF/Latch GSR_active hinder the constant cleaning in the block gsr_gen. You should achieve better results by setting this init to 0.
などには発生箇所が含まれません。
これではどうしようもないということになってしまいそうです。
フィルターで非表示にしたいメッセージって、まさにこういうやつだから。。。
Xst:2404 - FFs/Latches <state_mon<5:5>> (without init value) have a constant value of 0 in block <trimac_tx_ether>. Xst:1293 - FF/Latch <cmd1_4> has a constant value of 0 in block <vga_controller>. This FF/Latch will be trimmed during the optimization process. Xst:2677 - Node <cmd1_4> of sequential type is unconnected in block <vga_controller>. Xst:2260 - The FF/Latch <trimac/control/cpu/reset_flop1> in Unit <main> is equivalent to the following FF/Latch : <vga/sub/cpu/reset_flop1>
あたりはモジュール名が含まれているので良いのですが。
もがく?†
もはや、レポートファイルを自前でフィルタするスクリプトを書くしかない???
main.prj を合成すると、レポートファイルの名前は次のようになるようです。
- main.syr : Synthesis (xst)
- main.bld : Translation (ngbuild)
- main_map.map : Map (map)
- main.par : Place and Route (par)
- main.twr : Post-PAR Static Timing (trce)
- main.pwr : Power ()
- main.bgn : Bitgen (bitgen)
これらを自前でフィルタして、表示すれば、理論的には解決ですね(?!)
自前フィルタソフト†
仕方がないので2日掛かりで作りました。
いろいろしょぼいものの、これでも本家よりは使えるかもしれません?
SimpleMessageFilter-20100830.lzh
- 個々のメッセージに、モジュール名 / ファイル名 を付ける(できるかぎり)
- フィルタは正規表現で掛ける
- フィルタをグループ単位で on/off できる
- 各フィルタがマッチしたメッセージ数を表示できる
- 設定は *.filter という名前で保存されますが、Xilinx の filter.filter とは全く互換性がありません!!!考えてみるとひどい仕様でした(汗
使い方:
- Visual C# 2010 で作ったので、動作には .NET のランタイムライブラリが必要だと思います
- Result ページの上部に .syr ファイルを指定します( "..." ボタンが使えます )
- メッセージが読み込まれるので、フィルタしたいメッセージを選択して、 ダブルクリックあるいは右クリックから Create Filter します
- 作成されたフィルタの名前や、正規表現を、必要に応じて変更します
- Filters 画面では新しいフィルタを作ったり、フィルタをグループにまとめたりできます
- まとめられた子フィルタは、親フィルタがマッチした時のみ有効になります
- 空のフィルタはすべてのメッセージにマッチしますので、通常親フィルタの正規表現は空のままで使います
- Result 画面に切り替えると、新たに追加したフィルタが適用された結果が表示されます
- Filters 画面に戻ると、各フィルタが適用された回数が表示されます
- ISE で再コンパイルすると、自動的にメッセージが再読み込みされます
- フィルタの設定ファイルは *.filter と言う名前で保存しておくことができますが、 &COLOR(red){Xilinx の filter.filter とは全く互換性がありませんので、 上書きしてしまわないように注意して下さい}
需要があれば、後でもう少しまじめに使い方を書こうと思います。
コメント†
Perl のXMLパーサぢゃだめれすか?†
[アプロ] (2010-08-30 (月) 20:28:41)
ってやったことはないのですが、本とか、親切なWebサイトを読むと、簡単になんとかなりそう。とか思ったり(^^ゞ