ISim によるテストの自動化を考える のバックアップ差分(No.12)

更新


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

#contents

* テストを自動化したい [#u7f97791]

** テスト駆動開発 [#za66cb5b]

ソフトウェア開発で最近はやりの手法として、
テスト駆動開発(TDD: test-driven development)というのがあります。

Xilinx WebPack の ISim を使って Verilog による回路設計で
テスト駆動開発をやりたいというのがこの記事の趣旨になります。

** 背景 [#ce299d88]

ソフトでも、回路でも、プロジェクトが大きくなり複雑になると、
コードの一部を修正したことが思ってもみない部分に波及して、
新しいバグを生んでしまう(デグレードしてしまう)不幸が頻繁に起こります。

かといって、「動いているコードを変更するなんて愚の骨頂」
などという旧態依然とした態度でいると、
バグつぶしや新機能の導入のたびに場当たり的なつぎはぎが行われ、
コードの見通しが悪くなったり、
構造的なゆがみが蓄積してして、結局どこかで破綻をきたします。

そこで、コードに加えた変更がどこか他に悪影響を与えないことを確信できるようにして、
既存コードの改変を容易にしようというのがテスト駆動開発の原点になっています。

(ソフトの方ではテストを書くことで仕様が明確になるとか、
テストをしやすいモジュール構成にすること自体が結果的に見通しの良い設計を誘発するとか、
他にもいろいろ利点があることが宣伝されていますので、
興味のある方はググってみて下さい。)

gui がからむソフト開発に比べて、
回路は動作を機械的に定義しやすいので、
テスト駆動はとても向いてると思うのです。

** テスト駆動開発の流れ [#u89c3feb]

理想的なテスト駆動開発では、
コードを書いたり変更したりするのに先だって、
まずそのコードがクリアすべきテストを記述します。

そうやってテストを記述した後、実際のコードを書いて、
そのコードがちゃんとテストをクリアすることを確認して、
ようやく次のコードに移ります。

次のコードを書くときにはまた、先にテストを書いて、後からコードを書いて、
とやりますが、そのコードをテストする際には、はじめのテストと新しいテストの
両方が問題なく通ることを確認します。

つまり、後から書いたコードがそれ自身の目的を果たすだけでなく、
それまでに通っていたテストの結果を悪化させていないことも確認するわけです。

そのようにしていくと、コードが増えると同時に、テストもどんどん増えていき、
理想的にはすべてのコードがテストで守られている状況を作ることができます。

このようになっていれば、コードにどんな大きな変更を加えても、
その後テストを走らせることで
その変更が遠くの方でデグレードを引き起こしたりしていないという
確信を持てる理想的な状況を実現できます。

この安心感があるおかげで、
テスト駆動開発ではすでに動いているコード部分についても、
コードの読みやすさや構造的な改善のため、一部を改変することが容易であり、
常にコードを読みやすく、直しやすい状態に保つことができます。

このようなテストに裏打ちされた既存コードの改善
(動作を変えずに読みやすさや構成を改善する変更)は
専門用語で「リファクタリング」と呼ばれています。

** テストの自動化が重要 [#ud0d3c96]

上記のように、テスト駆動開発ではコードと同じか、
あるいはそれを上回る量のテストが書かれます。

そして、コードの主要な改変のたびに何百、何千もある
すべてのテストを走らせる必要があります。

したがって、普通にテストベンチを書いて、その結果の波形を目で追いながら確認する、
というような従来型のテストベンチの使い方は、テスト駆動開発では役に立ちません。

テスト駆動開発でのテストは、次のような自動テストであることが必須です。
+ テストはかならず「成功する」か「失敗する」かのどちらかを結果とする
+ すべてのテストを自動的に連続して走らせることができる
+ どのテストが成功して、どのテストが失敗したかを容易に把握できる

** ISim を使った自動テストに必要な技術 [#l6e21a7b]

上記の目的を果たす自動テストを ISim を使った Verilog 
コード検証で行うことを考えると、そのためには
Xilinx WebPack 上の ISim を使って、

- 「成功」か「失敗」かを返すテストベンチを書く方法
- 書きためた多数のテストベンチを一気に走らせる方法
- テストベンチの結果(成功・失敗)を一覧する方法
- そのあたりを考慮したプロジェクトフォルダ内のファイル配置

を確立する必要があります。

* どこかにまとめられてたりしません? [#kfb7e2c8]

で、こういう内容を駆け出しの私が一から考えても前途多難なのは目に見えているのですが、
経験に裏付けされたお勧めのプラクティスとか、どこかで紹介されてないでしょうか?

どなたか知っていたら教えて下さい。

二度目に四角い車輪を発明するような愚は犯したくないのです(−−;

** 見つけられないでいます(TT [#yee8fa28]

とはいえ、自分ではこれまで上記のような内容の記事を見つけられていません。

しかたがないので、以下で苦しむ過程を書きつつ、
何とか良さそうな解を探ってみようと思います。

今更こんなことを調べているのは不毛な気がするので、
どこかに答えがあればどなたかぜひ教えて下さい!

* 「成功」か「失敗」かを返すテストベンチの書き方 [#wdd688a8]

できればコード上でのテスト失敗位置を簡単に見つけられるようにしたいと考えて、
以下のようなマクロを使う方法を試しています。

これを使えば、ログに残ったエラーメッセージを見るだけで、
コードのどの部分でエラーが生じたかが一目瞭然になります。

テストベンチを書く際の手間が非常に小さくて済むのも
お勧めできる点です。

** テストベンチ記述に役に立ちそうなマクロ文法 [#saf52346]

 LANG:verilog
 `define ERROR(msg) \
    $display(`"%s(%0d) ERROR at #%0d: msg.`", `__FILE__, `__LINE__, $time)

としておいて、テストベンチ中で

 LANG:verilog
 if(variable!=expected)
     `ERROR(思ってたのと値が違う!);

と書くと、

 LANG:console
 C:/hoge_proj/moge_test.v(60) ERROR at #100: 思ってたのと値が違う!.

などというエラーメッセージを表示できます。

このようなエラー行からは、例えば秀丸のタグジャンプでソースファイルに飛べるのでとても便利。

- 実は上記の _LINE_ や _FILE_ は verilog2001 には規定されておらず、
ISim のマニュアルにも記述がないのですが、C の流儀で書いてみたら通ってしまいました
- ~`"〜`" という不思議なクォーテーションは、マクロ引数を展開してくれる書き方だそうです
- エラーの発生時刻は $time で得られます
- マクロが複数行にわたるときは \ で繋ぎます

** 自動テスト用テストベンチ記述に使うインクルードファイル [#x9c415ae]

 LANGUAGE:verilog
 `ifndef XILINX_ISIM
 
   // シミュレーション時以外は何もしない
 
   `define INFO(msg) 
   `define ERROR(msg) 
   `define DONE 
   `define ASSERT_EQ(variable, value) 
   `define ASSERT_EQ_ALWAYS(variable, value) 
   `define ASSERT_EQ_AT(variable, value, the_event) 
 
 `else
 
   // ISim 上での動作
   // ファイル名&行番号も表示する
   
   `define INFO(msg)   \
       $display(`"%s(%0d) INFO at #%0d msg.`",  `__FILE__, `__LINE__, $time)
   
   `define ERROR(msg)  \
       $display(`"%s(%0d) ERROR at #%0d msg.`", `__FILE__, `__LINE__, $time)
   
   `define DONE        \
       $display(`"%s(%0d) DONE at #%0d.`",      `__FILE__, `__LINE__, $time)
   
   // variable が value に等しいことを検証
   `define ASSERT_EQ(variable,value)                                             \
       if((variable)!==(value))                                                  \
           $display("%s(%0d) ERROR at #%0d: ", `__FILE__, `__LINE__, $time,      \
                    `"Assertion [ variable === value ] failed `",                \
                    variable, " != ", value, ".")
   
   // variable が常に value に等しいことを検証する always に展開される
   `define ASSERT_EQ_ALWAYS(variable, value)                                     \
       always @(variable, value)                                                 \
           if((variable)!==(value))                                              \
               $display("%s(%0d) ERROR at #%0d: ", `__FILE__, `__LINE__, $time,  \
                        `"Assertion [ variable === value ] failed `",            \
                        variable, " != ", value, ".")
   
   // variable が @(the_event) のタイミングで常に value に等しいことを検証する
   // the_event の部分は posedge clk とか negedge clk など @(the_event) 
   // としたときにおかしくない形で指定する
   `define ASSERT_EQ_AT(variable, value, the_event)                              \
       always @(the_event)                                                       \
           if((variable)!==(value))                                              \
               $display("%s(%0d) ERROR at #%0d: ", `__FILE__, `__LINE__, $time,  \
                        `"Assertion [ variable === value @ the_event ] failed `",\
                        variable, " != ", value, ".")
 
 `endif

テストベンチでこれをインクルードすれば、分かりやすいエラーメッセージを簡単に表示できます。

古い C でマクロを駆使してた頃を思い出しますが(−−;

- こういう場合、値の比較は != ではなく !== で行うのが良いですね。

** 波形を比較するというアプローチ [#v42d0aeb]

まずは波形を目視で確認する試験を行って、
もしうまく動いたことが確認できたならば、
そのときの波形を記録してしまえば、
信号値の理想波形が得られます。

そうしておいて、
その後のテストは実波形と理想波形との差分を取ることで行う、
という機械的なアプローチは、結構汎用的に使えるかもしれません。

パラメータによって
- 何もしない(目視のシミュレーション中)
- 実波形をファイルへ記録する(理想波形の記録)
- 実波形をファイルに記録された波形と比較して、必要に応じてエラーを吐く(以降のテスト)

の機能を切り替えられるようなデバッグ用のモジュールを作っておいて、
必要な信号線をありったけ繋いでおけば良さそうですね。

 LANG:verilog
 module wave_tester #(
     parameter FUNCTION  = "none", // "none" / "record" / "compare"
     parameter WAVE_FILE = "",
     parameter BIT_COUNT = 1,
     parameter PERIOD = 0  // >= 1 なら #PERIOD ごと、0 なら posedge clk ごとに検査
 ) (
     input wire gate,      // gate == 1 の時に限り検査される
     input wire [BIT_COUNT-1:0] data,
     input wire clk,       // PERIOD == 0 のときのみ使われる
     output wire error     // asserted when comparison fails
 );

こんな感じでしょうか?

信号波形の記録・読み出しには、アプロさんがコメント欄で教えて下さったように、
~$fopen, $fwrite, $fscanf 等が使えそうです。サブモジュールとする場合に、
~$fclose を呼び出すタイミングが難しそうですが・・・~
http://www.asic-world.com/verilog/verilog2k3.html

通常プログラムが終了する際にはすべてのファイルハンドルが自動で閉じられる
ことが多いので、手抜きで閉じなくても大丈夫だったり?

ただ、この形だと繋いだ信号線の信号名は失われてしまうので、
エラーが生じた際の原因究明にはちょっと手間がかかるかもしれません?

もっとうまい方法はあるでしょうか?

tcl で書いた方が良いという可能性も調べてみなければ。

** 成功と失敗の判別 [#cc762fd9]

エラーメッセージをログファイルに溜めておいて、
その中から "ERROR" という文字列が見つかれば失敗、
見つからなければ成功、という単純な見分け方ができるはず。

* 書きためた多数のテストベンチを一気に走らせる方法 [#vd7f748e]

多数のテストがあれば、
そのすべてを走らせるのに時間がかかってしまうのは仕方がないのですが、
それら1つ1つを手動でコンパイルして走らせるのは面倒なので、
バッチファイルあるいはmakefileのような物で一気にコンパイル&実行ができるようにしておいて、
後から結果だけを確認したいです。

本来なら ?Unit 系のツールのようにインターフェースを gui 化して、
そのとき必要な範囲のテストだけを選んで走らせる、
なんてこともできればよいのだけれど、そこまでは望めない・・・かな?

** テストのコンパイル&実行の基本コマンド [#m15c1502]

ISE から Simulate Behavioral Model をダブルクリックしたときの動作を追うことで、
コンパイルからシミュレータの起動までの一連の流れが Console に表示されますので、
それをなぞるスクリプトを書けばよいことになります。

*** はじめに環境を整える [#gaf00001]

C:\Xilinx\12.4\ISE_DS\settings32.bat あるいは C:\Xilinx\12.4\ISE_DS\settings64.bat 
を起動することで、Xilinx 
のコマンドラインツールを使うのに必要な環境変数が正しくセットされます。

 Language:Console
 C:\hoge_proj>C:\Xilinx\12.4\ISE_DS\settings64.bat

私はテスト用のツールを cygwin 環境で使いたかったので、~
C:\Xilinx\12.4\ISE_DS\settings64.bat を同じディレクトリに~
C:\Xilinx\12.4\ISE_DS\settings64-cygwin.bat という名でコピーして、~
その中の

 REM Execute command if any

という行以降を

 C:
 chdir C:\cygwin\bin
 bash --login -i

に書き換えて、独自のスクリプトを作りました。

この .bat のショートカットを作成して、プロパティから
- 編集オプション : 簡易編集モード
- フォント
- レイアウト
- アイコン

等の設定をいじって、ISim デバッグ用のコンソール起動アイコンとして利用しています。

*** テストベンチソースファイルを fuse でコンパイルして *_isim_beh.exe ファイルを作る [#h7ad85c5]

私は hoge モジュールのテストベンチに hoge_test 
と言う名前を付けているので、
通常の呼び出しは以下のようになっています。

 LANG:console
 fuse                                 \
        -intstyle ise                 \
        -incremental                  \
        -lib unisims_ver              \
        -lib unimacro_ver             \
        -lib xilinxcorelib_ver        \
        -o hoge_test_isim_beh.exe     \
        -prj hoge_test_beh.prj        \
        work.hoge_test work.glbl

ここで参照している hoge_test_isim_beh.prj には
 verilog work "hoge.v"
 verilog work "hoge_test.v"
 verilog work "fuba_module.v"
 verilog work "C:/Xilinx/12.4/ISE_DS/ISE//verilog/src/glbl.v"

のように、テストベンチ hoge_test が依存するモジュールファイルが記述されています。

~.prj ファイルは ISE からテストベンチを起動するときに自動で作られるものですが、
何か別の作業をしているといつの間にか消えてしまうようです?

モジュールの依存関係を自前で解析するのは骨が折れるので、
このファイルを別ディレクトリに取っておいて、
自動テストにそのファイルを使うことにしました。

*** *_isim_beh.exe の実行 [#u665164d]

できあがったシミュレータを実行するときは、
標準入力に run を送ってやる必要があります。
(もちろん、バッチファイルを記述しても良いのですが、
標準入力に run を送った方が楽なので、ここではそうしています)

また、標準出力をファイルにリダイレクトすることでログを取ることができます。

 LANG:console
 $ (echo run | hoge_test_isim_beh.exe) > hoge_test_isim_beh.log
 $ cat hoge_test_isim_beh.log
  ISim log file
  Running: hoge_test_isim_beh.exe
  ISim M.81d (signature 0x12940baa)
  Time resolution is 1 ps
  Simulator is doing circuit initialization process.
  C:/hoge_proj/foba_test.v(66) ERROR Assertion [ value == expected ] not met at #0: 0 != 1
  Finished circuit initialization process.
  C:/hoge_proj/foba_test.v(60) ERROR エラーが起きた!
  C:/hoge_proj/foba_test.v(62) DONE.
  Stopped at time : 100 ns : File "C:/hoge_proj/foba_test.v" Line 63

run コマンドにより、テストベンチは自ら $finish; で終了するまで走り続け、
その間に、もしエラーが生じればログファイルにログを残します。

** 複数のテストベンチを一括で自動実行するには [#i2987a2b]

ISE が作ってくれる *_isim_beh.prj ファイルを多数 beh/ フォルダに入れておいて、
下記の ruby スクリプトを走らせると、
それらを順番にコンパイルして実行することができます。

 LANG:ruby
 #!/usr/bin/ruby
 
 # 古いログファイルを消す
 system("rm simulate_all.log")
 
 # .prj ファイルすべてをコンパイル&実行する
 Dir.glob("beh/*.prj").each do |prj|
   prj =~ /([^\/]+)_beh.prj/
   module_name = $1
   prj = $~                          # 先頭の beh/ を取り除く
   system("cp beh/#{prj} #{prj}")
   system("fuse "+
     		"-intstyle ise "+
       		"-incremental "+
       		"-lib unisims_ver "+
       		"-lib unimacro_ver "+
       		"-lib xilinxcorelib_ver "+
       		"-o #{module_name}_isim_beh.exe "+
       		"-prj #{prj} "+
       		"work.#{module_name} work.glbl")
   system("echo ===== #{module_name}_isim_beh.exe >> simulate_all.log")
   system("echo run | ./#{module_name}_isim_beh.exe >> simulate_all.log")
 end

この場合、実行結果は simulate_all.log と言うファイルにログとして残ります。

ただ、まだいろいろ改善したいところも残ってます。

*** 必要なファイルだけコンパイル&実行したい [#k364db4c]

上記スクリプトではファイルが更新されたかどうかにかかわらず、
すべての .prj をコンパイル&実行しています。
ログファイルとソースファイルのどちらが古いかをみて、
必要な物だけ実行するよう変える必要がありますね。

*** テストベンチ .exe の挙動がおかしい [#baf8f5fb]

上記で、一応動くことは動くんですが、
コンパイルしてできた *_isim_beh.exe ファイルを実行する際に、
私の環境では内部で fork してすぐに返ってきてしまうようで、
シミュレーションの終了を待たずに次のコンパイルが始まってしまいました。

これだとPCに余計な負荷がかかるだけでなく、ログファイルにはき出される
ログの順序が乱れてしまうことも考えられます。

この現象、スクリプトからでなく手動で起動した場合にも、
tcl コマンドのプロンプトがバックグラウンドプロセスに
回ってしまっているような動作をしていて、とても不思議です。

Windows7 64bit で動かしているのがいけないとか?

もう少し調査してみますが、最悪は Windows API 
でプロセス一覧を調べるようなアホなことをしなきゃならないかも。

*** fuse のソース検索パス [#f8597286]

fuse は .prj ファイルのある位置を基準に
HDLソースファイルを探しに行くようで、.prj ファイルを一段下の beh/ 
フォルダに置いたままだとうまくコンパイルすることができませんでした。

今は .prj ファイルをプロジェクトフォルダにコピーしてから
fuse を起動しているのですが、中間ファイルがすべてプロジェクトフォルダに
できてしまうため、望ましくありません。

このあたりも、もう少し詳しく調べる必要がありそうです。

最悪一時ファイルは自動的に消してしまうと言う対処でも良いんですが・・・

*** コンパイルエラーが生じたときの対応 [#d23043df]

そうそう、コンパイルエラーへの対処もちゃんとしなきゃ。

* テストベンチの結果(成功・失敗)を一覧する方法 [#kd26a735]

ログファイルを grep あるいは ruby かなにかのスクリプトで
処理すればできるんじゃないかと考え中。

簡単には、
 LANG:console
 $ grep -E "ERROR|^=====" simulate_all.log | nkf -s

とすることで、実行したテストベンチ名と、
その中でもしあればエラー行のみを一覧表示できるようです。

* プロジェクトフォルダ内のフォルダ構成をどうするのが良いか [#yb72c04c]

これ結構重要だと思うんですが、試行錯誤が必要になりそうでもあります。

今の ISE だとプロジェクトフォルダ内は一時ファイル等で
ぐちゃぐちゃになるので、ソースファイルを一段下に置くことにして、

 (project_home)/.git/
 (project_home)/.gitignore
 (project_home)/project.xise
 (project_home)/ipcore_dir/some_core.xise
 (project_home)/ipcore_dir/some_core.v
 (project_home)/iseconfig/filter.filter
 (project_home)/src/hoge.v
 (project_home)/src/fuba.v
 (project_home)/src/test/hoge_test.v
 (project_home)/src/test/hoge_test2.v
 (project_home)/src/test/hoge_test3.v
 (project_home)/src/test/fuba_test.v
 (project_home)/src/geda/geda.v
 (project_home)/src/geda/bopa.v
 (project_home)/src/geda/test/geda_test.v
 (project_home)/src/geda/test/bopa_test.v
 (project_home)/beh/hoge_test_beh.prj
 (project_home)/beh/hoge_test_beh.wcfg
 (project_home)/beh/hoge_test2_beh.prj
 (project_home)/beh/hoge_test2_beh.wcfg
 (project_home)/beh/hoge_test3_beh.prj
 (project_home)/beh/hoge_test3_beh.wcfg
 (project_home)/beh/fuba_test_beh.prj
 (project_home)/beh/fuba_test_beh.wcfg
 (project_home)/beh/geda_test_beh.prj
 (project_home)/beh/geda_test_beh.wcfg
 (project_home)/beh/bopa_test_beh.prj
 (project_home)/beh/bopa_test_beh.wcfg
 (project_home)/beh/temp/hoge_test_beh.exe
 (project_home)/beh/temp/hoge_test_beh.log
 (project_home)/beh/temp/hoge_test2_beh.exe
 (project_home)/beh/temp/hoge_test2_beh.log
 (project_home)/beh/temp/hoge_test3_beh.exe
 (project_home)/beh/temp/hoge_test3_beh.log
 (project_home)/beh/temp/fuba_test_beh.exe
 (project_home)/beh/temp/fuba_test_beh.log
 (project_home)/beh/temp/geda_test_beh.exe
 (project_home)/beh/temp/geda_test_beh.log
 (project_home)/beh/temp/bopa_test_beh.exe
 (project_home)/beh/temp/bopa_test_beh.log

なんてのを考えています。

テストベンチとソースを全然違うフォルダに置いてしまうと探しにくいので、
ルート直下のフォルダで分離するという形にはしていません。

シミュレーション結果のログファイルを、
テストベンチごとに異なる名前にしておけば、
その .log ファイルと、関連ソースファイルと、
どちらが新しいかを比べて、必要なテストだけを走らせることができそうです。

自動テスト中にコンパイルした .exe ファイルは、
ログファイル生成後は必要ないので、
エラーが出ない限りは消してしまっても良いかも?

エラーが出た場合には gui を起動して原因を探るかもしれないので取っておく?

手動で波形を目視によりデバッグする際には、
gui 上に表示する波形の設定を保存した .wcfg
ファイルも重要なんですが、現状ではこのファイルは ISE 
が管理していないため、
どこに置いても使いにくいことには変わらない状況です。

エクスプローラの拡張子の関連づけでうまくやれば
.prj ファイルのダブルクリックで、同じディレクトリにある
.wcfg ファイルを使って gui を起動することもできるかも?
あ、.wcfg ファイルの方を関連づけした方が良いかな?
後でまた検討します。

* とりあえず上記方針でやってみる [#x4a0c197]

プロジェクトフォルダの構成とか変更して、
試してみようと思います。

git はファイルの移動も覚えてくれるはずなので、
とりあえずやってみて、うまくいかなければ戻せばいいはず。

ファイルの移動の巻き戻しとか、あんまりやったこと無いけど(^^;

* ISim 13.1 ではいろいろ変わるらしい [#z77c8942]

ISim 12.4 のマニュアルによると、
ISim 13.1 ではシミュレータを落とさずにテストベンチを再コンパイルできるようになるそうです。

ModelSim XE と ISim との比較の記述を抜粋>
>シングルクリックコンパイルおよび更新
>
>ModelSim XE では、スタンドアロンGUI にテキストエディタがビルトインされているので、HDL コードの変更、再コンパイル、および再シミュレーションが実行できます。
>
>ISim GUI にはテキストビューアはありますが、テキストエディタはありません。ファイルに変更しても、再コンパイルおよび再シミュレーションは実行できません。既存のシミュレーションを閉じて、再起動する必要があります。この制限は、13.1 のISim で修正される予定です。


そうなると、生成されるのは .exe ではなく .dll になるんでしょうし、
現状でいろいろ工夫しても、すぐにはしごを外されるのかもしれません。

ModelSim XE の時がそうだったし・・・~
書きためた数十の .fdo/.udo ファイルとか、消すのももったいないけど、
すでに無用の長物とか、泣けてきます(TT

どうするのが良いのか、迷ってます。

* コメント [#h77e4c69]

#article_kcaptcha
**テストベンチで全部まかなう [#jf37d06a]
>[アプロ] (2011-02-16 (水) 18:48:34)~
~
期待値はテストベンチ内で用意し、テストベンチ内で、コンペアして、結果はログ・ファイルに出力する~
~
波形はデバッグ時に見るが、OK・NGはログ・ファイルで確認する~

//
- やはりその方向ですよね。現在、その方針で自分なりのコーディング規約を作ることと、そういうテストベンチが多数あったときに、自動的にすべて走らせて結果を一覧にまとめる方法を調べています。良い方法があったら教えて下さい。 -- [武内(管理人)] &new{2011-02-16 (水) 18:55:21};
- 相手のなんちゃってモデルを作って接続する。または、メーカーのシミュレーション・モデルと接続する。そーすると、CPUアクセスがメインになったり、そのなんちゃってモデルの制御になるため、コンベアが楽になります -- [アプロ] &new{2011-02-16 (水) 19:43:24};
- SystemVerilogでテストベンチが書けると、かなりイロイロと効率が上がりますが・・・taskとfunctionの塊になりますよ。テストケース毎にtask化するとデバッグが楽になります。また、共通化taskを作っておいて、それをコールしまくる -- [アプロ] &new{2011-02-16 (水) 19:47:13};
- $system(); は使えるかな? シェルをコールするシステムタスクです。Verilogで出来ないことは、外部プログラムで補う。perlとかを呼ぶことができる -- [アプロ] &new{2011-02-16 (水) 19:49:20};
- Verilog の規格のドラフト版を探してみてください。どっかに転がっていると思います。内緒ですが、アレは、ヒントが満載なんですよ -- [アプロ] &new{2011-02-16 (水) 20:31:55};
- SystemVerilog が使えるという意味でも modelsim は魅力的だったんですよね。ISim ではまだ実装されていない部分が多そうなので、自分でまかなうしかなさそうです(TT -- [武内(管理人)] &new{2011-02-16 (水) 20:37:34};
- いろいろ勉強になります。いろいろやりながら試行錯誤になりそうです・・・ -- [武内(管理人)] &new{2011-02-16 (水) 20:39:22};
- OVLも使ってみたらどうでしょうか? -- [marsee] &new{2011-02-16 (水) 21:27:45};
- OVLも検討中なのですが、エラーが出た時に何をさせればデバッグに役立つかが見えてこなくてペンディングになってしまっています。 -- [武内(管理人)] &new{2011-02-16 (水) 22:20:31};
- できると良いのは、最低限エラーが起きたことをログファイルから見分けられることですが、できればログファイルからコードのどの部分で、どのシミュレーション時刻に、どんなエラーが生じたかが分かることなのですが・・・ -- [武内(管理人)] &new{2011-02-16 (水) 22:21:24};
- テストケースは、taskにして、for でループさせるとよいですよ。ひとつのテストベンチで済みます -- [アプロ] &new{2011-02-17 (木) 08:11:59};
- テストベンチ部品の task 化、便利に使っています。verilog 言語は task や function のスコープがモジュール内限定のグローバルであることや、テストベンチでは下位モジュール内の信号やイベントに直接介入可能であることなど、言語仕様に自由度が大きいので、自分なりのコーディング規約が定めにくく、経験不足を感じています。 -- [武内(管理人)] &new{2011-02-17 (木) 09:05:44};
- http://www.asic-world.com/verilog/verilog2k1.html (2k2, 2k3とすると次のページが出ます) task、function に automatic を付けると、コールされるとメモリに動的に生成します。これで、task、function 内でローカル変数をバシバシ使ってください -- [アプロ] &new{2011-02-17 (木) 18:29:24};
- ログファイルは、テストベンチ内で、ファイル名を生成することで、いかようにも制御可能になります -- [アプロ] &new{2011-02-18 (金) 12:17:58};
- automatic 知りませんでした。付けないと同時に呼び出せないんですね。テストベンチ内からログファイルを開くのも一考の余地がありそうです。 -- [武内(管理人)] &new{2011-02-18 (金) 22:17:58};
- Verilog HDL&VHDLテストベンチ記述の初歩 by CQ出版 はどーでしか? 目次を見た限りでは、よさそうな気がします。私も買ってはいないのですが(笑) -- [アプロ] &new{2011-02-21 (月) 12:19:23};
- 買って、積んで、忘れてましたw パターンファイルを使った検証あたりなどは上で考えているのとかぶるところも多そうですね。改めて見なおしてみます。 -- [武内(管理人)] &new{2011-02-21 (月) 12:40:11};

#comment_kcaptcha


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