2014年11月20日木曜日

isimをcliで呼んでみた

ISEについているisimは実はcommand line interfaceがある。これを使ってguiを使わずにシミュレーションしようぜっていう話。ISim User GuideとかISim In-Depth Tutorialとかを参考にしている。

isimはGUI modeとCLI modeがあって、CLI modeだとtclの対話環境があってそれを使う。走らせるtestが事前にあるならbatch scriptを走らせることもできる。そうじゃなくても短ければ標準入力からpipeとかで与えると動く。何も考えなければ

 
  run all
とか
 
  run 10ms
とか与えればよい。終わったらexitで抜けられる。

これだと波形が見れないが、debugするのであれば波形を見たい。vcdファイルを吐けば良いが、isimのvcd出力はverilog用っぽくて情報が欠けているようだ。そこでisimの波形のフォーマット(?)のwcfgとwdbを使うと良い。

こういうtclのbatchを書いて、(fadd_sim.tclとする)

  $ ./fadd_sim -wdb fadd.wdb -tclbatch fadd_sim.tcl
のようなことをするとfadd_sim.wcfgとfadd.wdbが生成される。波形を見たいときはこんな感じで見ることができる。

  $ isimgui -open fadd.wdb -view fadd_sim.wcfg

isimで自動テストを回してみた

ハードウェアでも自動テストをやると捗るので自動テストを回してみた。自動テストをやるのにいちいち波形を見る方法は取りづらいので、想定される出力と一致するかのみを判定して、一致しなければsimulationを止める方法で正誤判定を行った。まず、isimの実行ファイルをcliで作るのには依存関係を記述した,prjファイルが必要である。

下記のようなprjファイル(fadd_sim.prjとする)を作る。この例だと、fadd_simを作るのにwork libraryのfadd.vhd,fadd_sim.vhd,fadd_stage1.vhd,fadd_stage2.vhd,fadd_stage3.vhd,right_shift.vhd,ZLC.vhdが必要だという意味である。

次にMakefileを書く。これは普通に書けば良い。


fadd_isim: fadd_sim.prj fadd.vhd fadd_sim.vhd fadd_stage1.vhd fadd_stage2.vhd fadd_stage3.vhd right_shift.vhd ZLC.vhd
        fuse -incremental -prj $< -o $@ fadd_sim
test: fadd_isim
        ./run.sh

最後にtestを回す次のようなスクリプトを書く(run.shとする)。

#!/bin/sh
# please change this variable when test target is changed
tests="fadd_isim i2f_isim"
ERROR_MES="User(VHDL) Code Called Simulation Stop"
NUM=$(echo $tests | wc -w)
PASSED="0"
FAILED="0"
if [ $NUM -eq 1 ]; then
echo -e "\e[32m[==========]\e[0m Running 1 test";
else
echo -e "\e[32m[==========]\e[0m Running $NUM tests";
fi
for a in $tests; do
echo -e "\e[32m[ RUN ]\e[0m $a";
if echo "run all" | ./$a | grep "$ERROR_MES" > /dev/null; then
echo -e "\e[31m[ FAILED ]\e[0m $a";
FAILED=$(( $FAILED + 1));
else
echo -e "\e[32m[ PASSED ]\e[0m $a";
PASSED=$(( $PASSED + 1));
fi;
done
echo -e "\e[32m[==========]\e[0m";
if [ $PASSED -eq 1 ]; then
echo -e "\e[32m[ PASSED ]\e[0m $PASSED test.";
elif [ $PASSED -gt 1 ]; then
echo -e "\e[32m[ PASSED ]\e[0m $PASSED tests.";
fi;
if [ $FAILED -eq 1 ]; then
echo -e "\e[31m[ FAILED ]\e[0m $FAILED test.";
elif [ $FAILED -gt 1 ]; then
echo -e "\e[31m[ FAILED ]\e[0m $FAILED tests.";
else
exit 0;
fi;
exit 1;
view raw run.sh hosted with ❤ by GitHub

これを実行すると次のようになる。

[==========] Running 2 tests
[ RUN      ] fadd_isim
[  PASSED  ] fadd_isim
[ RUN      ] i2f_isim
[  PASSED  ] i2f_isim
[==========]
[  PASSED  ] 2 tests.