MPLAB SIM で入出力のシミュレート

2005/08/22

いろいろなスティミュラス

 PICのプログラム開発では、MPLABがよく使われます。
 MPLABもいつの間にかバージョンが7.20になっています。
 アセンブルやコンパイル、ステップ、トレース、ブレークなどの方法はほとんど変わっていませんが、 入力をシミュレートするスティミュラスの使い方は、
大きく変わってしまったようです。

 MPLAB SIMの基本的な部分の使い方については、MICROCHIP社のサイトに MPLAB IDE v6.xxクイックスタートや、Ver4.00のMPLAB(R)Getting Started-MPLABチュートリアル があるので(両方とも日本語)、そちらの方が簡単でわかりやすく説明されています。

 ここでは、それらのデータシートの内容から大きく変わってしまった部分について、簡単な非同期のスティミュラスから、 SCLファイルを使ったちょっと複雑なシミュレートまで説明してみます。
(MPLAB IDE User's Guide[英語版]には詳しく載っているようです。)
 
 デバイスはPIC12F675を使用した例で説明します。

 
1.Asynchronous Stimulus(非同期入力)

 まずは簡単な非同期スティミュラスから。
・テスト用ソース
・GPIOの出力状態を見るためのWatchウィンドゥ
・時間経過を見るためのStopWatchウィンドゥ
  これは、簡単なテストプログラムですので、実際にPICに書き込んでも期待した動作はしません。
  (入力にスイッチなどを使用する場合は、チャッタリングの除去が必要です。)
 プログラムの内容は、GP<3>に'H'パルスが入るたびに、GP<0>からGP<2>の3ビットが順次カウントアップされていくものです。

 出力は、Watchウィンドウなどで見ればわかります。
 入力をシミュレートするのに、ここではAsynchronous Stimulus(非同期入力)を使ってみます。
 このAsynchronous Stimulusでは、プログラム実行中にあるピンに対して、
  • [Set High]:クリックするとそのピンをHighにする。
  • [Set Low]:クリックするとそのピンをLowにする。
  • [Toggle]:クリックするたびにそのピンがHighとLowを繰り返す。
  • [Pulse High]:クリックするとそのピンを一定時間(例えば20msとか)Highにしてその後Lowに戻る。
  • [Pulse Low]:クリックするとそのピンを一定時間(例えば20msとか)Lowにしてその後Highに戻る。
の様な入力を与えることができます。

・メニューから新しいシナリオを開く

 Saveしてあるシナリオ(.stcファイル)を開く場合は、
New ScenarioでなくOpen Scenarioで行う。

 テストに使ったソースファイル(test675.asm)と、
右の設定が保存されているファイル(TestAsync.stc)
 をまとめたzipファイルはここ
・動作などを入力するウィンドウ


 まず、MPLABのメニューからDebugger→Stimulus Controller→New Scenarioとたどって、Stimulus Controllerウィンドウを開きます。
   [Pin/SFR]の欄では入力したいピンを選びます。
   [Action]の欄ではどんな入力をするか選びます。 [Pulse …]を選んだ場合には[Width]と[Unit]の欄でそのパルス幅を入力します。
    ここでは、[Set Low]と[Pulse High]の2種類設定してみました。
    下の[Pulse High]だけでもいいのですが、GP<3>が'H'のときにプログラムを停止してしまうと'L'に戻らなくなる場合があるため[Set Low]も入れてみました。
 プログラム実行中に[Fire]欄の2番目の[ > ]をクリックすると、50usのパルスがGP<3>に入力されます。

 プログラムの実行は[Run][Animate][Step]のどれでもいいのですが、
   [Run]の場合は実行速度が速いが、設定によっては実行途中の結果が表示されません。
   [Animate]の場合は実行速度が遅いが、実行中のソース行やレジスタの内容などが順次表示されます。
   [Step]の場合は複雑だったり長いプログラムではシミュレートに時間がかかるが、分岐やフラグの変化などが確実に観察できます。


 このテストプログラムでは、Fire[ > ]をクリックするたびに、
GPIOの下3ビットが'000'から'001'→'010'→'011'→'100'…と
変化していくのがわかる。

   このシナリオの状態を保存しておきたい場合は、[Save Scenario]をクリックして.stcファイルとして保存します。
 
 
2005/08/23
2.Synchronous Stimulus - Clock Stimulus(同期入力 - 繰り返しパルスの入力)

 前述の1.Asynchronous Stimulusでは、Stimulus Controllerウィンドウを開いて動作条件などを入力しましたが、ここで行うSynchronous Stimulusでは
[SCLファイル]が必要です。
 通常、[SCLファイル]はSCL Generatorで生成します。

 少々複雑なので図に表してみました。


1.非同期入力の場合は、最低限Stimulus Controllerに
 条件を入力すればシミュレートできます。
  後で条件を変更して利用したい場合には、
  シナリオ(.sti)ファイルとして保存しておくことによって
  Stimulus Controllerに読み込めます。

2.同期入力の場合は、最低限SCLファイルが必要です。
  SCLファイルはテキストファイルなので、エディタなどでも
  作製できますが、通常はSCLジェネレータに条件を入力して
  SCLファイルを生成します。
  SCLファイルの内容を変更しない場合は、SCLファイルのみ
  残しておけば、いつでもシミュレートできますが、
  SCLファイルはSCLジェネレータに読み込めませんので、
  条件などを変更して再利用したい場合は、ワークブック(.sbs)
  ファイルとして保存しておきます。

 それでは、同期入力の中でも比較的簡単な繰り返し波形の入力を行います。

・新しいSCLジェネレータ(New Workbook)を開く

 Saveしてあるワークブック(.sbsファイル)を開く場合は、
New WorkbookでなくOpen Workbookで行う。

 テストに使ったソースファイル(test675-2.asm)と、
右の設定が保存されているファイル(GP3-10kHz.sbs)
 と生成されたSCLファイル(GP3-10kHz.scl)
 をまとめたzipファイルはここ
・動作などを入力するウィンドウ

 繰り返し波形の入力は、Clock Stimulusタブで条件を入力する。
 

 このClock Stimulusでは、
  • [Pin]:クロックを入力するピンの選択。
  • [Initial]:そのピンの初期値(LowまたはHigh)。
  • [Low Cyc]:ピンがLowになっている時間(クロックサイクル数)。
  • [High Cyc]:ピンがHighになっている時間(クロックサイクル数)。
  • [Begin] [End]:クロックを出し始める条件。クロックを停止する条件。
の様な条件を指定することができます。

 ここでは、GP<3>に初期値'Low'、'Low'の期間が80サイクル、'High'の期間が20サイクルの10kHz(OSCクロックが4MHzの場合)のパルスを設定しました。
 この状態で、[Genetate SCL From Workbook]をクリックするとSCLファイルが作成されます。


 SCLファイルが作成されたらStimulus
Controllerで読み込みます。


 [Attach]をクリックすると、
SCLファイルを読み込むダイアログが出てくる。


 1.の非同期入力ではここで直接シミュレートの
条件を入力したが、ここではファイルを読み込む
だけです。

 SCLファイルを読み込んだ後は、
このウィンドウで特に操作は必要ないが、
このウィンドウを閉じてしまうと
読み込んだSCLファイルが無効となって
シミュレートされないので、
このウィンドウが邪魔な場合は
他のウィンドウを手前に出すか、
最小化するなどしておかなければいけない。







 Stimulus Controllerで読み込めばシミュレートできます。

 StepやAnimateで実行させてWatchウィンドウで状態を確認する以外にも、 GPIOのピンの状態を確認する方法があります。

メニューからView→Simulator Logic Analyzerを選択し、ロジックアナライザーを開きます。


 [Channels]で状態を確認したいピンを選択します。
 [Mode]にSimpleと表示されていますが、不明です。
 [TimeBase]は横軸の間隔を選択しますが、このバージョンでは'Cyc'しか選択できないようです。
 [Trigger Position]と[Trigger PC =]はセットで使用します。
   ピンの状態などを記憶できる量には限りがありますので、複雑で長いプログラムを実行させた場合などは
  プログラムの最後のほうしか記憶、表示されません。
   したがって、表示したい部分を「記憶表示したいアドレス」と「そのアドレスの前/前後/後」で指定します。
 [+]と[−]はズームですが、これは縦と横同時にズームされますので、使い道はあまりありません。
 その左の[Zoom(Axes)]をクリックした後、横軸目盛付近をクリックすると、マウスでのドラッグや矢印キーでズームできるようになります。
 ズームした状態で移動したい場合は、更に左の[Move(Axes)]をクリックすると、同様に移動できます。

 このロジックアナライザーは表示されるタイミングに注意する必要があります。
  ・Step Into、Step Overでcall以外の実行、Animateの場合は表示が更新されません。
  ・Step Overでcallを実行、またはRunで実行しブレークポイントで停止した場合は表示が更新されます。
 任意の場所で表示を更新したい場合は、一つ先のアドレスにブレークポイントを設定し、Runでアドレスを進めます。


 ソフトウェアによるRS-232Cの出力や、クロック同期シリアルデータの出力なども観察でき、
Watchウィンドウによるピンの変化より確認がしやすい場合も多くあります。



2005/08/24
3.Synchronous Stimulus - Pin/Register Actions(同期入力 - 任意パルスの入力)

 RS-232Cの入力など、送信側の決めたタイミングで送られてくるパルスをシミュレートするのが[Pin/Register Actions]です。

 今までと同様に、メニューからDebugger→SCL Generator→New Workbookを開きます。
 一番左の[Pin/Register Actions]のタブを使用します。
 ピンを追加するには[Click here to Add Signals]をクリックします。


 ・失敗例

 ・成功例
 一例として、初期値'0'、500us後に'1'(スタートビット)
その後(9600bpsと仮定し)104us毎に'00101101'ときて、
'0'(ストップビット)が来る パルスを作成してみました。



 左側の方が直感的でわかりやすいと思ったのですが、
うまくいきませんでした。

 Timeに指定する値は全てプログラム実行開始時からの
時間になるようです。

 右側のものは、Timeの値をひとつ前の値に間隔を
加算した値を設定するように修正しました。

 今までと同様に、生成されたSCLファイルを
Stimulus Controllerに読み込んでシミュレートします。



 生成されるSCLファイルはテキストファイルなので、
エディタなどで内容を見ることができます。
 SCLファイルの言語仕様のようなものは見当たらなかった
のですが、いろいろな条件を設定し、SCLファイルを生成
してみると、なんとなくその規則が見えてきます。
 うまくいけばSCLジェネレータで設定できないような条件も、
SCLファイルを修正することによって可能になるでしょう。


 こんな感じでパルス入力をシミュレートできます。




2005/08/25
4.Synchronous Stimulus - Advanced Pin/Register(同期入力 - 任意パルスの入力[条件付])


 ここでは、クロック同期入力のシミュレートを行ってみます。

 例えば、次のような入力信号をシミュレートします。
 ・PICが何も出力しない時は、何の入力信号も発生しません。
 ・PICがGP4にパルスを出力する毎に、その立ち上がりから80ns遅れてGP5にデータが入力されます。
 ・データは'1'、'0'、'1'、'0'の順とします。


 例によって、新しいワークブック(SCLジェネレータ)を開きます。

 [Advanced Pin/Register]タブを使用します。

 ・まず、下半分に条件を入力します。
   GP4が'1'になってから80ns待つと起動されます。

 ・次に、上半分にその条件になったら何をするか入力します。
   ここでは、GP5に対して'1'、'0'、'1'、'0'を順に入力します。

 最後に、[Generate SCL …]をクリックしてSCLファイルを生成します。

 今回は、ここで生成されたSCLファイルの内容を見てみることにします。


 左側が生成されたSCLファイルです。

 最初の5行(//ダブルスラッシュ)はコメントです。

 次のconfiguration〜end configuration;は不明です。
  いくつかSCLを見てみましたが、全て空でした。
  もっといろいろなSCLファイルを作ってみないとわからないようです。

 その次のtestbench〜end testbench;の中に実際の動作が書かれています。

 左のSCLファイルでは、testbench〜end testbench;の間にprocess〜end process;が4つあります。
  これでは、この4つの動作がそれぞれ独立してしまって期待通りの動作ができません。
  例えば、この4つが別々の条件で、別々のピンに対する入力を指示しているのならうまく動作するでしょう
  ところが、今回はこの4つを順番に動作させたいのでうまくいきません。

 そこで右側のようにSCLファイルを書き換えてみました。
  もしかすると単に操作方法を知らないだけで、SCLファイルを書き換えなくても別の入力方法があるのかもしれません。    
wait until GP4 == '1';
wait for 80 ns;
GP5 <= '1';
wait until GP4 == '0';  

  各processから、この3行を取り出して全てのprocessを結合してしまいます。

 ・最初のwait until GP4 == '1';はGP4の出力が'1'になるのを待ちます。
  これは、単に'1'かどうかではなく、'0'から'1'への立ち上がりを見ているようです。
  したがって、このような行を連続して記述しても、そのピンが一旦'0'にならないと次へ進みません。

 ・次のwait for 80 ns;は、単に指定時間待つ動作が行われます。
  ただし、ここで指定したように80nsのような極めて短い時間は有効かどうかわかりません。
  12F675が4MHzのクロックで動作しているので、ちょうど1step実行するのに1usかかるため、それより短い時間は意味が無いかもしれません。

 ・次のGP5 <= '1';は、GP5に'1'を入力します。
  一般にプログラミング言語で'<='の記号は大小の比較に使われますが、ここではピンやレジスタにセットするという意味のようです。

 ・ここまでが一つのクロックに対する1ビットのデータ入力のシミュレートですが、次のクロックの立ち上がりを待つために一旦クロックの立下りを待たないと
 次のクロックの立ち上がりに進まないようなので、wait until GP4 == '0' を入れておきます。
(2005/11/09追加修正)

 ・process内の最後の行にあるwait;は、ここでprocess内の処理が終了することを意味しているようです。
  process内の最後の行にwait;ではなく、wait for xx(時間指定);やwait以外の処理が書かれている場合は、processの最初に戻って、 繰り返し実行されます。


 実際に動作させるとGP4の立ち上がりからわずかに遅れてGP5にデータが入力されているのが見られます。


 いくつかのSCLファイルを見て、これらのほかに次のようなものもありました。

 report 'xxx'; … アセンブルエラーなどを表示するOutputウィンドウにメッセージを表示します。
  SCLファイルの中のどの場所が処理されているのか見る場合などに使用するといいでしょう。

 wait for (時間指定)の単位にns(ナノセコンド)、us(マイクロセコンド)、ms(ミリセコンド)以外があります。
  SCLジェネレータでいろいろ指定してみて、実際に実行させてみないと詳しいことはわかりません。

 loop〜end loop; … Clock Stimulusを使用した時に出力されます。
  前述のように、processも最後にwait;が無ければ繰り返し処理されます。
  はっきりとした使い分けはわかっていません。

 まだほかにもSCLファイルに出力されるものがあるかもしれませんが、このくらい覚えていれば、「やりたいことがSCLジェネレータで入力できない。」 とか、「思ったとおりに入力が入ってこない」等の時にSCLファイルの内容をチェックし、または書き換えることができるでしょう。

 このページに書いてある内容はあくまで一例で、
MPLAB7.20 SIMのStimulusを使い始めるきっかけとなるよう書いたものです。
正確で詳しい内容は、HELPやUser's GUIDEなどに書かれているでしょう。
バージョンが上がれば使い勝手の悪い部分が修正されたり、操作方法などが変更になるかもしれません。
つづく・・・


PIC Writerのページ
     
Topページ