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); 〜