MPLABでシミュレータを自動操作する手段にSCL(Stimulus Control Language)のスクリプトがある。
このスクリプトはIDEで設定して自動生成することが多いけれど、手書きで作成することも可能だ。
スクリプトの記述力は十分とは言えないものの、ファイル操作・文字列検索のAPIや、標準出力(SimulatorのOutput)を操作するreport()のAPIなど、最低限の機能が揃っている。UARTやテスト用IFがなくとも、シミュレータ上のソフトウェアを自動操作し出力を比較検証することが可能となっており、自動テストにも使えるので、簡単に例をメモ。
記述例
例えばPICで動作するソフトウェアを対象として、UARTでデジタル出力を操作し、その結果を評価するスクリプトならば、以下のようになる。
testbench for "pic12f1822" is
begin
process is
begin
report("start");
RCREG <= 16#E2#;
wait for 10 ms;
if RA0 == '1' then
report("ra0-0 fail");
else
report("pass");
end if;
if RA1 == '0' then
report("ra1-1 fail");
else
report("pass");
end if;
wait;
end process;
end testbench;
また複雑なスクリプトは、MPLABで生成して、手描きで追加編集すると作りやすい。
例えばファイルでリストアップした文字列をUART入力する処理をSCL化すると、以下の様なスクリプトが生成される。
これに「elsif match(〜」の行を追加してオリジナルのイベント命令を追加したり、report()を挿入したりすれば、それなりの自動テストのスクリプトに組み替えられる。
〜
file_open(status_RCREG, data_file_RCREG, "input_data.txt", read_mode);
if status_RCREG == open_ok then
while endfile(data_file_RCREG) == false loop
readline(data_file_RCREG, pkt_line_RCREG);
// skip empty line and comment line
if match(pkt_line_RCREG, "") == true then // do nothing
elsif match(pkt_line_RCREG, "//") == true then // do nothing
else
if match(pkt_line_RCREG, "wait ") == true then
read(pkt_line_RCREG, dummy_RCREG); // to consume 'wait' command
read(pkt_line_RCREG, waitime_RCREG);
wait for waitime_RCREG;
new_packet_RCREG := true;
elsif match(pkt_line_RCREG, "rand ") == true then
read(pkt_line_RCREG, dummy_RCREG); // to consume 'rand' command
read(pkt_line_RCREG, rand_lower_RCREG);
read(pkt_line_RCREG, rand_upper_RCREG);
read(pkt_line_RCREG, rand_unit_RCREG);
random_time(rand_lower_RCREG, rand_upper_RCREG, rand_unit_RCREG,
rand_seed1_RCREG, rand_seed2_RCREG, randime_RCREG);
wait for randime_RCREG;
new_packet_RCREG := true;
else
if new_packet_RCREG == true then
packetin(pkt_line_RCREG, RCREG, false); // new packet
wait until RCREG_packet_done;
new_packet_RCREG := false;
else
packetin(pkt_line_RCREG, RCREG, true); // append to previous
wait until RCREG_packet_done;
end if;
end if;
end if;
end loop;
else
file_close(data_file_RCREG);
wait;
end if;
file_close(data_file_RCREG);
〜