言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

ModelSim で遊ぶ

気分転換に FPGA を再開。でも FPGA ボードをどこでも持ち歩く訳には行かないので、ModelSim の使い方を調べてみました。ModelSim を使うと、職場でも仕事サボって Verilog で遊ぶ事が出来るので便利です。ISE のチュートリアルには ISE と ModelSim を連動して動かす説明があるのですが、動くときと動かない時があって非常にムカつくので、ModelSim だけで遊ぶ事にしました。

ダウンロード

ModelSim とはハードウェア記述言語のシミュレーターで、Xilinx のサイト(http://www.xilinx.com/ise/mxe3/download.htm)から無料版がダウンロード出来ます。Windows XP しか対応しないと書いてありますが、私は VMware 上の Vista で動かしています。

インストールするとライセンスを聞かれます。指示に従うと無料版のライセンスを Xilinx のサイトから取得出来ます。このライセンスをインストールする時に環境変数になにやら書き込むのですが、私の場合この時ハングしました。再起動して環境変数が変わったのを確認してもう一度やると上手く行きました。

準備。ライブラリの作成。

後はヘルプの中にあるチュートリアルを参考に進めます。同じような物を http://www.actel.com/documents/modelsim_tutorial_ug.pdf にも見つけました。

ModelSim では、Library というやつを作ってそれにシミュレートしたい ソースを登録して使います。Library の他に Project というのもありますが、まだよくわかりません。とりあえず、以下のファイルを適当なディレクトリに保存して実験しました。

// my_counter.v
// テスト対象カウンタ

`timescale 1ns / 1ps // 意味はよくわからないが ps の数字を変えるとシミュレータで一度に進む時間が変わる。

module my_counter(input CLK, input RESET, output reg [7:0] counter);

    always @(posedge CLK) counter <= counter + 1; // CLK が 1 になったらカウンタ増分
    always @(posedge RESET) counter <= 0; // RESET が 1 になったら カウンタ増分

endmodule
// my_counter_test.v
// テストスクリプト

module my_test_counter;

   reg CLK, RESET; // クロックとリセット信号
   wire [7:0] COUNT; // カウント信号

   my_counter counter1 (CLK, RESET, COUNT); // カウンタを一つ作る

   initial // 初期設定
     begin
	CLK <= 0;
	RESET <= 0;
	#5 RESET <= 1; // 5 ステップ後にリセットを 1 に
	forever #10 CLK <= !CLK; // 15 ステップ後にクロックを 1 にして 10 ステップごとにトグル
     end
   
   initial
     // デバッグ表示
     $monitor($stime, " CLK=%b RESET=%b COUNT=%d", CLK, RESET, COUNT);
    
endmodule    

File - New - Library でライブラリの名前を指定します。デフォルトの work のままで OK していいです。

それから Compile - Compile... で、実験するファイルを選択し Compile を押します。エラーが出たら Transcript に赤い字で出るのでそれを直して、完了したら Done を押します。

シミュレート

Library タブの work の中に、my_counter と my_test_counter が出来ていると思います。my_test_counter をダルブクリックすると端子の名前が書いた Object と、これから波形が表示される Wave というウインドウが開きます。開いてなかったら View メニューで開けます。

sim タブを開き、my_test_counter を右クリック、Add > Add All Signals to Wave で端子の名前が Wave ウインドウに表示されます。

run ボタンを押すと 100 ps 分だけシミュレートしてくれます。Wave ウインドウに波形が表示されて、Transcript に次のように結果が表示されれば動いています。

#          0 CLK=0 RESET=0 COUNT=  x
#          5 CLK=0 RESET=1 COUNT=  0
#         15 CLK=1 RESET=1 COUNT=  1
#         25 CLK=0 RESET=1 COUNT=  1
#         35 CLK=1 RESET=1 COUNT=  2
#         45 CLK=0 RESET=1 COUNT=  2
#         55 CLK=1 RESET=1 COUNT=  3
#         65 CLK=0 RESET=1 COUNT=  3
#         75 CLK=1 RESET=1 COUNT=  4
#         85 CLK=0 RESET=1 COUNT=  4
#         95 CLK=1 RESET=1 COUNT=  5

ソースを編集してやり直すときは、

  • Library タブでモジュールを選んで右クリックで Recompile。
  • テスト用モジュールをダブルクリックして sim タブを開く。
  • テスト用モジュール右クリック Add > Add All Signals to Wave (ここよく忘れる!)。
  • run ボタン

を繰り返します。これがうざい人は、面白い事に GUI で操作した内容が Transcript 画面にコマンドとして表示されるので、これを実行すれば良いです。例えばこんな感じです。

vlog -work work -O0 C:/Users/takashi/Documents/fpga/counter/my_counter_test.v
vsim work.my_test_counter
add wave -r /*
run

このようなメニューとコマンドラインが両方使える開発環境はたまに見かけますが、使えるコマンドを学習しやすい HyperCard を彷彿させる無茶苦茶画期的な GUI / CUI だと思います。