ModelSim で $messagelog を使う のバックアップの現在との差分(No.2)

更新


  • 追加された行はこの色です。
  • 削除された行はこの色です。
[[公開メモ]]

#contents

* Xilinx が ModelSim の無償版&廉価版の配布を中止との情報 [#ta34907b]

http://marsee101.blog19.fc2.com/blog-entry-1570.html

Xilinx 向けには ModelSim は敷居の高い環境になってしまいました。

* $messagelog が便利 [#qc78c59d]

verilog のテストベンチで画面にテキストを表示するには、
通常 $display を使うのですが、

ModelSim では $display の代わりに $messagelog を使うと便利です。

例えばテストベンチに

 LANG:verilog
 always @(posedge iclk_int)
     if (full & we)
         $messagelog("Write strobe was asserted while fifo is full.", "Error")
         $messagelog("%:S Write strobe was asserted while fifo is full.", "Error")

と書いておけば、$display のように出力ウィンドウにメッセージを表示すると共に、
下図のように wave ウィンドウの message 欄にメッセージが表示された時刻を示す ▼ 
が表示されます(&COLOR(blue){青丸};)。

&attachref(message_log.png);

▼ の上にカーソルを持って行けば表示されたメッセージを見ることができますので、
$display に表示された時刻を目で追うような苦労から解放されます。

また、message 欄のタイトル部分(&COLOR(red){赤丸};)をクリックすることで、
アクティブなカーソルを次の ▼ まで飛ばすことができます。

したがって、通常 ▼ を目で探す必要もありません。

メニューの [View] - [Messsage Viewer] にチェックを入れておくと、
wave ウィンドウの隣に Message Viewer タブが出ます(&COLOR(purple){紫丸};)。
ここでは次のように、表示されたメッセージを条件別に並べ替えて表示するようなことが可能です。

&attachref(message_viewer.png);

(ちょっとメッセージ内容が違っているのは下記のルーチンを使っているためです)

$messagelog では %:S にメッセージの種類を指定できて、
表示されるメッセージはこれを使って分類されます。

よく使われるのは "Note" と "Error" だと思いますが、
-"Note" ("Info", "Message" も同義)
-"Warning"
-"Error"
-"Fatal"

の4つが使えるそうです。

この %:S の内容で ▼ の色が変わるので、
重要なメッセージとそうでない物を一目で見分けられます。

その他の使い方については ModelSim の User's Manual 
を参照して下さい。

* $messagelog を利用するマクロ [#u3affc0e]

上記の通り $messagelog はとても便利なのですが、
そのままソースコードに書き込んでしまうと、
ModelSim 以外でテストするのが難しくなってしまいます。

そこで、$messagelog を直接呼ぶのではなくマクロを使って記述することにしました。

simulation.inc
 LANG:verilog(linenumber)
 `ifndef VERBOSE
     `define VERBOSE 0
 `endif
 
 `define INFO(msg) \
     if(`VERBOSE) \
         $messagelog(`"%:S msg.`", "Note")
 
 `define ERROR(msg) \
     $messagelog(`"%:S msg.`", "Error")
 
 `define DONE \
     $messagelog(`"%:S Done.`", "Note")
 
 `define ASSERT(variable,value) \
     if((variable)!=(value)) \
         $messagelog(`"%:S Assertion [ variable == value ] was not met.`", "Error")
 
 `define ASSERT_ALWAYS(variable,value) \
     always @(variable) \
         if((variable)!=(value)) \
             $messagelog(`"%:S Assertion [ variable == value ] was not met.`", "Error")
 
 `define ASSERT_AT_CLK(clk,variable,value) \
     always @(clk) \
         if((variable)!=(value)) \
            $messagelog(`"%:S Assertion [ variable == value @ clk ] was not met.`", "Error")
 
上記コードを `include して使うことで、
ModelSim 以外でシミュレーションする必要が生じたときにも
このマクロ定義だけを書き換えれば済みますので、
便利な機能を安心して使えます。

* ASSERT マクロ群 [#uc3ec9a3]

本来ならこういったことをするのには OVM のような、
本来ならこういったことをするのには OVL のような、
標準的な検証ライブラリを使うべきなのでしょうけれど、
使い方を覚えるのが面倒なのに加えて、
記述量を減らしたいという欲求もあって、
上記のようなマクロを書いて使ってしまっています。

ASSERT や ASSERT_ALWAYS を書くのには SystemVerilog の構文を使っています。
従って、vlog のオプションに -sv を加えておかないと、コンパイルエラーが生じます。
注意して下さい。

やり方は、
+ ISE Project Navigator の Processes ペインで Simulate Behavioral Model を右クリック
+ Process Properties
+ Category で Simulation Properties が選択されているはず
+ Other VLOG Command Line Options に -sv を追加

です。

同じ所に "+define+VERBOSE=1" を書くことで、
VERBOSE マクロを書き換えて `INFO マクロによる出力を無効化することもできます。


上記のようにわざわざ SystemVerilog の構文を使っているのは、
与えた条件からエラーメッセージを自動生成するためです。
この自動生成のおかげでアサーションを記述するのがとても楽になっています。

上記 FIFO の例であれば、

 LANG:verilog
 always @(posedge iclk_int)
     if (full & we)
         $messagelog("Write strobe was asserted while fifo is full.", "Error")
         $messagelog("%:S Write strobe was asserted while fifo is full.", "Error")

の代わりに

 LANG:verilog
 `ASSERT_AT_CLK(posedge iclk_int, full && we, 0);

とするだけで、

 # ** Error: Assertion [ full && we == 0 @ posedge iclk_int ] was not met.

という分かりやすいメッセージが出力されます。

※ 本当はメッセージ中の full && we を括弧でくくらないと間違いなのですが、
それはそれで見難いので、そのままになっています。
条件式の方は括弧で括ってあるので大丈夫です。
(full && we == 0 だと full && (we == 0) の意味になってしまいます )

メッセージにはエラーの発生箇所が含まれていませんが、
上記の通り発生時刻は Wave Window で分かりますし、
コード中での位置は Message Viewer を使えば調べられます。

エラーメッセージはあまり長くない方が見やすいようです。

* 検証コードをソースに埋め込む [#g854ecdb]

上記のような検証コードはテストベンチに記述しても良いのですが、
ロジックを記述したソースコードに直接埋め込んでおくのも便利です。

FIFO のソースコード中に

 LANG:verilog
 `include "simulation.inc"
 ...
 
 module fifo (
   ...
 
 );
 
    ...
 
    // synthesis translate_off
    `ASSERT_AT_CLK(posedge iclk_int, full  && we, 0);
    `ASSERT_AT_CLK(posedge oclk_int, empty && re, 0);
    // synthesis translate_on
 
 endmodule

のように、synthesis translate_off / synthesis translate_on 
で挟んで検証コードを埋め込んでおくと、
インプリメント時にはこの部分が無視されるので、
ソースコードを変更することなく検証と合成のどちらも行えます。

** 注意 [#ybf136d7]

恐らく、上記のようにソースに埋め込んだの検証コードは Behavior 
レベルのテストでしか効果がありませんので、
合成結果に対するテストでは別途テストベンチに検証コードを記述する必要があるのだと思います。

* コメント [#n2213283]

#article_kcaptcha
**勉強になりますた(^O^) [#ef1e0401]
>[アプロ] (2010-08-27 (金) 20:16:46)~
~
いつも、あの緑の逆三角形はなんだろう?~
と疑問だったんですが、これで氷解しました~
~
オレのアサーションもいいですが、OVLもなかなか便利そうですよ~
まだ、一部しか使えてませんが・・・(笑)~

//
- はい、便利そうだなー、とは思ってるんですが、パラメータがたくさんあって書くのが面倒そうなのに加え、追加でライブラリが必要なところとかがあって、食指が動かないところなのです(汗 -- [武内(管理人)] &new{2010-08-27 (金) 22:36:00};
- 検証に関しては HDL レベルでどんなライブラリを使うかよりも、今は多数のテストをどのように自動実行して、結果を確認するかに興味を持っています -- [武内(管理人)] &new{2010-08-27 (金) 22:41:23};
- ソフトウェアのテスト駆動開発のように、常にテストしながら開発できれば気軽にリファクタリングができて便利なんだと思うのですが、HDL開発でそういう環境を整える方法とか、どこかにあればぜひ知りたいです -- [武内(管理人)] &new{2010-08-27 (金) 22:42:08};
- そーすっと、VMM,OVMになるような感じです。または、SystemVerilogでテストベンチを作成するかですねぇ。SystemVerilogでテストベンチを作成するとすごく便利ですが -- [アプロ] &new{2010-08-28 (土) 12:41:33};
- 情報ありがとうございます。いただいたキーワードを元に調べてみようと思います。Xilinx から ModelSim が手に入らなくなると言うことで、いろいろできることが限られてきそうだと心配しています。今から Altera に乗り換える方が得なのかどうか、とか。何だかオフトピックですが、頭が痛いです。 -- [武内(管理人)] &new{2010-08-28 (土) 14:13:22};
- OVL の導入は、インクルードするだけなので、簡単ですよ -- [アプロ] &new{2010-08-28 (土) 16:31:18};
- 続きです。付録のPDFに、波形イメージの使い方が載っています。テストベンチ側に、どんどん、アサーションしたいモジュールを追加してゆくイメージです。イネーブル/ディセーブルができるので、テストケース内でコントロールが効きます -- [アプロ] &new{2010-08-28 (土) 16:33:55};

#comment_kcaptcha


Counter: 12055 (from 2010/06/03), today: 2, yesterday: 0