まえおき
XilinxのFPGA開発環境(ISE)に含まれているHDLのシミュレータ(ISIM)を、コマンドラインから起動する手順について紹介します。
メリット
ISIMは、ISEからGUI操作で起動するのが簡単な方法ですが、コマンドラインから起動することにより以下ののうなメリットがあります。
- ISEによる予備処理が不要(起動までが少し早くなる)
- ISEを立ち上げなくて良い
- 多重起動が可能(ISEから起動すると1本しかSIMが走らない)
- ログだけ落として終了できるので、BATで流すことで何本ものSIMを自動で実行できる。
環境
- Windows7
- ISE14.7
手順
全体てきな流れは以下のとおりで、これを実現するスクリプトをBATとTCLで記述していきます。
- パスを通す
- Verilog/VHDLをコンパイルする
- シミュレーション実行ファイルを生成する
- 実行ファイルを起動する
- シミュレーション時刻を進める
- シミュレーション実行ファイルを終了させる
パスを通す
ISEのアイコンを”右クリック”→"プロパティ"とすすむと下図のように"リンク先"が表示されます。
ISE14.7とくにカスタムしないでインストールした場合は↓のようになっていると思います。
前半に書いてあるバッチファイルで環境変数を設定した後、ISEを起動していることが分かります。
C:\Xilinx\14.7\ISE_DS\settings64.bat C:\Xilinx\14.7\ISE_DS\ISE\bin\nt64\ise.exe
コンパイル
パスを通すと以下のコマンドが使用可能になりますので、HDLファイルをコンパイルしてゆきます。
コマンド | 説明 |
---|---|
vhpcomp | VHDLファイルをコンパイルする |
vlogcomp | Verilogファイルをコンパイルする |
バッチファイルのあるディレクトリを見に行くと、32bit用と64bit用のバッチファイルがありますので、環境に合わせた方のファイルの中身を見ます。
バッチファイルの中身は↓のようになっています。
@echo off
REM Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved.
REM Set current working directory
set XIL_SCRIPT_LOC=%~dp0
REM Remove trailing slash
set XIL_SCRIPT_LOC=%XIL_SCRIPT_LOC:~0,-1%
REM Call settings file for each product
set xlnxInstLocList=
set xlnxInstLocList=%xlnxInstLocList% common
set xlnxInstLocList=%xlnxInstLocList% EDK
set xlnxInstLocList=%xlnxInstLocList% PlanAhead
set xlnxInstLocList=%xlnxInstLocList% ISE
for %%d in (%xlnxInstLocList%) do (
if EXIST %XIL_SCRIPT_LOC%\%%d\.settings64.bat (
call %XIL_SCRIPT_LOC%\%%d\.settings64.bat
)
)
REM Unset XIL_SCRIPT_LOC
set XIL_SCRIPT_LOC=
REM Execute command if any
if "%1" neq "" (
if /i "%~x1" == ".bat" (
call %*
) else (
start %*
)
)
REM Unset xlnxInstLocList
set xlnxInstLocList=
ちょっとややこしい感じですね。。。
サブフォルダの"common","EDK","PlanAhead","ISE"の中にある"settings64.bat"を順次実行しているので、中身が気になる方は、”隠しファイルを表示”して、見てみてください。
要点だけまとめます
環境変数の"PATH"に以下4つを加えてやればOKということらしいです。
- C:\Xilinx\14.7\ISE_DS\ISE\bin\nt
- C:\Xilinx\14.7\ISE_DS\ISE\lib\nt
- C:\Xilinx\14.7\ISE_DS\ISE\~~~\DocNav
- C:\Xilinx\14.7\ISE_DS\ISE\
なので、作成するバッチファイルの冒頭には↓の記述を入れます。共通部分を一度"Xilinx"という変数に入れていますが、
これが、__ISEのアイコンのプロパティで参照していたBatファイルのあるディレクトリ__になるようにします。
set XILINX=C:\Xilinx\14.7\ISE_DS\ISE
set PATH=%XILINX%\bin\nt;%XILINX%\lib\nt;%XILINX%\..\..\..\DocNav;%PATH%
コンパイル
パスを通した後は以下のコマンドが使用可能になりますので、HDLファイルをコンパイルしてゆきます。
コマンド | 説明 |
---|---|
vhpcomp | VHDLファイルをコンパイルする |
vlogcomp | Verilogファイルをコンパイルする |
コンパイル対象のソースファイルは"-f"オプションを使用することで、外部ファイルに記述できますので、
-fオプションを使用して、以下のようにBATファイルに記述します。
set VHDL_LIST=.\src\SIM_LIST_vhd.txt
set VERILOG_LIST=.\src\SIM_LIST_v.txt
vhpcomp -work work -f %VHDL_LIST%
vlogcomp -work work -f %VERILOG_LIST%
実行ファイル作成
"fuse"コマンドを使用することで、work空間にあるコンパイル済ライブラリから、実行ファイルを生成します。
引数には、__work.<テストベンチトップ階層名>__を与えます。
fuse work.%TB_NAME%
シミュレーション実行
fuseコマンドで生成したexeファイルを実行し、シミュレーションを走らせます。
fuseコマンドで-oオプション(生成する実行ファイル名の指定)をしなかった場合__"x.exe"__という実行ファイルが生成されていますので、これを実行します。
今回使用しているオプション(引数)は以下3つです。
- -tclbatch
- ISIM実行時の処理を記述したTCLスクリプトを読み込ませることができます
- -log
- 実行時のログを落とすファイル名を指定できます
- -gui
- このオプションをつけるとGUIを起動してシミュレーションを行います(波形が見える)
x.exe -tclbatch %TCL_OPTION% -log tmp.log -gui
TCLスクリプト
TCLスクリプトの例を紹介します。
U0階層(検証対象モジュールのTOP階層)の波形を全表示し5us時刻を進める場合の例です。
# エラー時の対応設定
onerror {resume}
# 波形を追加(U0の階層すべてHEXで表示)
wave add /U0 -radix hex
# シミュレーションを実行
run 5us;
# CUIで走らせるなら最後exiしておく(GUIなら落としたくないのでコメントアウト)
# exit
TCLスクリプトの書き方について、今回説明は省略しますが、詳細はISIMのユーザーガイドに書いてあります。
作成例
ここまで紹介した内容をもとに作成したbatファイル(SimRun.bat)を↓に紹介します。
これを実行することで、ISEを使用しないでISIMによるシミュレーションを実行することが可能です。
@echo off
rem 対象のVHDLファイルを指すリスト
set VHDL_LIST=.\src\SIM_LIST_vhd.txt
rem 対象のVerilogファイルを指すリスト
set VERILOG_LIST=.\src\SIM_LIST_v.txt
rem SIM実行時に読み込ませるTCLファイル
set TCL_OPTION=.\src\SIM_OPTION.tcl
rem テストベンチTOP階層名
set TB_NAME=EdgeDet_tb
rem -------------------------------------------------------------
rem ①パスを通す
rem 変数(XILINX)にISEの起動BATファイルのあるパスを入れる
rem -------------------------------------------------------------
set XILINX=C:\Xilinx\14.7\ISE_DS\ISE
set PATH=%XILINX%\bin\nt;%XILINX%\lib\nt;%XILINX%\..\..\..\DocNav;%PATH%
rem -------------------------------------------------------------
rem ②コンパイル
rem VHDLは "vhpcomp" Verilogは "vlogcomp"を実行する。
rem -workオプションでワークディレクトリ名を指定(指定しないを勝手にworkになる)
rem -f オプションで指定したテキストファイルに書いてあるファイルを参照
rem -------------------------------------------------------------
vhpcomp -work work -f %VHDL_LIST%
vlogcomp -work work -f %VERILOG_LIST%
rem -------------------------------------------------------------
rem ③実行ファイル生成
rem -oオプションで実行ファイル名を指定(指定しないとx.exeになる)
rem -------------------------------------------------------------
fuse work.%TB_NAME%
rem -------------------------------------------------------------
rem ④シミュレーションを実行
rem -tclbatch :実行オプションを記述してあるTCLファイルを読み込ませる
rem -log :ログをダンプするファイル名
rem -gui :GUIで走らせる
rem CUIで実行する場合はtclの最後でexitする必要がある
rem -------------------------------------------------------------
x.exe -tclbatch %TCL_OPTION% -log tmp.log -gui
rem rename tmp.log %TESTBENCH_NAME%_%File%.txt
rem ---------------------------------------------
rem 要らないファイルを消す
rem del:ファイル削除 rd:ディレクトリ削除 /q:確認なし
rem ---------------------------------------------
del /Q fuse.log
del /Q fuse.xmsgs
del /Q fuseRelaunch.cmd
del /Q isim.wdb
del /Q x.exe
del /Q tmp.log
rd /s /q isim
pause
作成例の動作環境
- 任意のディレクトリに先ほどの”SimRun.bat”を置く
- サブディレクトリとしれ"src"フォルダを作成し、以下5つのファイルを置く
【Verilogのファイルを列挙したリスト】
.\src\EdgeDet_tb.v
【VHDLのファイルを列挙したリスト】
.\src\EdgeDet.vhd
【検証対象回路】
library ieee;
use ieee.std_logic_1164.all;
entity EdgeDet is
port(
i_clk :in std_logic ;--クロック
i_rst :in std_logic ;--リセット(Hリセット)
i_src :in std_logic ;--ソース信号
o_rise :out std_logic ;--立上りエッジ
o_fall :out std_logic );--立下りエッジ
end entity;
architecture rtl of EdgeDet is
signal buf_ff :std_logic_vector(0 to 2) ;--Dフリップフロップ
signal rise :std_logic ;--立上り検出パルス
signal fall :std_logic ;--立下り検出パルス
begin
process(i_clk,i_rst)begin
if(i_rst='1')then
buf_ff <="000";
rise <='0';
fall <='0';
elsif(Rising_edge(i_clk))then
--Dフリップフロップ
buf_ff(0) <=i_src;
buf_ff(1) <=buf_ff(0);
buf_ff(2) <=buf_ff(1);
--立上り検出
if(buf_ff(1 to 2) ="10")then
rise <='1';
else
rise <='0';
end if;
--立下り検出
if(buf_ff(1 to 2) ="01")then
fall <='1';
else
fall <='0';
end if;
end if;
end process;
o_rise <=rise;
o_fall <=fall;
end architecture;
【テストベンチ】
`timescale 1ns/1ps
module EdgeDet_tb();
reg i_clk =1'b0 ;
reg i_rst =1'b1 ;
reg i_src =1'b0 ;
wire o_rise ;
wire o_fall ;
//検証対象モジュール
EdgeDet
U0 //インスタンス名はTCLスクリプトで共通化するためでU0に統一する
(.i_clk (i_clk )
,.i_rst (i_rst )
,.i_src (i_src )
,.o_rise (o_rise )
,.o_fall (o_fall )
);
//クロック
always#5 i_clk=~i_clk;
//リセット
initial #26 i_rst=1'b0;
//入力信号
initial begin
#320;
i_src=1'b1;
#500;
i_src=1'b0;
#450;
i_src=1'b1;
#300;
i_src=1'b0;
#300;
$stop;
end
endmodule
【TCLスクリプト】
# エラー時の対応設定
onerror {resume}
# 波形を追加(U0の階層すべてHEXで表示)
wave add /U0 -radix hex
# シミュレーションを実行
run 5 us;
# CUIで走らせるなら最後exiしておく(GUIなら落としたくないのでコメントアウト)
# exit
シミュレーションの実行
作成した”SimRun.bat”をコマンドプロンプトから叩くか、ダブルクリックすることで、一連の処理が流れます。
- 実行時の応答
多重起動時の注意点
- 実行時のルートディレクトリそれぞれ別のところにする。
連続実行時の高速化方法
回路は変更せずに、__テスト条件だけ変更してSIMを繰り返す場合__は、実行ファイルをそのまま使用することが可能です。
よって、fuseまでの処理は1回のみで x.exeの実行を繰り返し行うことで済みますので、コンパイル時間分が短縮できます。
※ただし、変更する条件は外部ファイルに記述しておき、実行時に読み込むような構成にする必要があります。