ご希望の方は、お問い合わせページから資料閲覧パスワードをお問い合わせ頂きログインをお願い致します。アカウント名は"opendocument"です。"Ultra96"既に発行済みのブログであっても適宜修正・追加することがあります。IPは、Verilogステートマシン設計されているため、Vivadoのロジックシミュレータでステート毎に値をチェックして行きました。飛び先である\$FF12を用意されているものの、PCに書き込まれていないことが判りました。言え、JMP命令は正しくデコードされ、内部信号のop_JMP(JMP命令であることを示すデコード信号)は正しく出力されています。修正前の6809CPUの動作ステート遷移を修正し、レジスタ書き込みで終わっている箇所をジャンプステートに修正し、さらに、PCへの書き込みアサートを追加しました。(09=次の命令フェッチ)のように遷移し、かつ、オレンジ色で示したk_write_pc信号がアサートされ、new_pcである\$FF12\$FF12がPCにセットされています。結果として正しく\$FF12にジャンプしています。\$12(SEQ_GRAL_WBACK)と、レジスタ書き込みのステート遷移となっているのに対して、修正後は\$1b(SEQ_JMP_LOAD_PC)と、JMP命令のステートに遷移しています。メインフレームのような大型機をどのようにテストしているかと言えば、もちろん単体命令をひとつづつテストすることも行いますが、キャッシュ、仮想記憶、ページングの記憶階層があります。そのためのタイミングによるバグの可能性があるので、ランダム試験を実施します。命令を乱数で発生し、ただし不正命令とはならないように制約をかけ、ソフトシミュレータで正解値を取得します。これを論理シミュレータにかけ、結果値であるレジスタの値やメモリの値が正しいかをチェックします。メモリの値はひとつずつチェックすることなく、領域のチェックサムを取ることで確認します。これを発展させ、実機にランダムプログラム生成プログラムを載せて、実行時に正解値を生成しチェックします。バグ値どうしを比較してOKとなりそうですが、いろいろと条件を変え、命令をページクロスさせて前半と後半でキャッシュやページのヒットミスを変えることで、演算値が変わることがあり得ます。これはプロセッサがパイプライン動作していることから、バグによってはタイミングによって結果が変わることがありうるためです。いうことで、メインフレーム並みの信頼性を保証するなら、上記のようなテストを実施しなければなりません。2019FM=7のハードウェアエミュレーションをFPGAで実行するプロジェクトを遂行していましたが、FM-7のROMイメージもZ80カードI/Fを用いることにより、すんなり抜き出すことができました。それをVivadoに持ち込むにあたって、COEファイルという形式に変換し、OpenCoresからダウンロードした6809を動かしたのですが、動作しないようです。実機の動作と比較するために、実機にはロジックアナライザを接続しました。前記事のArduino-Z80I/FカードにはFM-7の内部バスが現れているので、実はArduinoは動かさなくても、ロジックアナライザを接続すれば、メインCPUである6809の動作が把握できます。ロジックアナライザも昔は数百万円したかと思いますが、私の購入したものは17,000円くらいでした。400MSa/sですから、アドレス、データ、主要制御信号を観測するのに十分です。https://www.banggood.com/Hantek-4032L-Logic-Analyzer-32Channels-USB-Oscilloscope-Handheld-2G-Memory-Depth-Osciloscopio-Portat-p-1376105.htmlのように比較的気軽に試すことができます。このような環境でFPGAのシミュレーションを実行したら、おかしな点を見つけました。具体的にはJMP命令が動作しません。work.」とのことで、自分でなんとかするしかなさそうです。FM-7システムの中で6809をデバッグするのは大変なので、新たに図のような単体テスト環境を作成しました。CPUに、リセット、クロック、ROMを接続しただけです。end最初の\$FF03番地のJMPを、JMPせずに実行してしまいます。JMP命令でもインデックスアドレシングのみ動作しないようです。0,Xは動作は同じですが、オペコードは異なります(\$6E,\$00と\$6E,\$84)。0,Xのオペコードがアセンブラから出力されるため、やむなく上記のようにFCBで記述しました。2019サブシステムのROM吸出しの際に、サブシステムの動作確認をするために、Arduinoからランダムなボックスフィルを実行してみました。FBASICで描画しているように見えますが、Z80カードのエミュレーションをArduinoがやっています。その様子を図160.1に示します。以下の動作をするスケッチを作成しました。2019メインシステムROMの吸出しは非常に単純で、アドレスをセットして、データをリードするだけでしたが、サブシステムのROMはサブシステム側に依頼しないと読み出せません。従って、前に述べたように、メンテナンスコマンド(いわゆるYAMAUCHIコマンド$\dagger$)を用いてブロックコピーし、分割読み出しすることになります。これは、サブシステムのROMが10,240バイトもあるのに比べて、窓である共有メモリがわずか128バイトしかなく、コマンドにいくらか使用するため、データ転送用の窓を64バイトとしているためです。そのため、この転送を160回繰り返します。64バイト毎に16進ダンプを行います。Subシステムメンテナンスコマンドのページを参考にスケッチを作成します。作成したスケッチをここに置きました。サブROMコピーの動作図いちいちサブシステムを止めてコマンドを(2度)発行してダンプを行うので、かなり面倒でしたが、このスケッチにより得られたダンプ画面の最初と最後を示します。00同じくネットで入手したSubrom_c.romと比較したところ、全てのバイトが一致しました。若干疑問なのは、スクラッチから作成したと言われているROMデータが実ROMデータを全て一致するということがあるのだろうかということです。実機から抜き出したROMデータを使用している分には問題が無いので、気にしないことにします。$\dagger$山内さんは入社した時の課内ソフトウェアグループのサブシステムチームのリーダでした。Proの端子図を図158.1及び図158.2に示します。Proの端子図(右側の端子)アドレス、データ、制御信号を全てソフトコントロールしています。スケッチはここに置きました。初版からデータピンの位置を変更しているため、ボードの版数に合わせて適宜修正する必要があります。ROM(\$8000~\$FBFF)生データの一部を示します。8bこのままCOEファイルに変換するか、あるいはバイナリにすれば、前稿のスクリプトが使えますが、簡単なのでこのままawkによりCOE化することにします。ネットで入手したFM7エミュレータ用のROMデータと実機から吸い上げた生データを比較したところ、fbasic30.coeは全てのバイトが一致しました。lineが不一致となりました。エミュレータ用のROMでは0xffとなっていますが、実機のROMは割込みベクタが置かれているためにデータが入っています。ROMではないため、これで全てのバイトが一致しました。末尾32バイトはベクトル領域というRAM領域でジャンプテーブルとなっています。飛び先のRAMの内容を含めて表にまとめます。割込みベクタまとめ表FIRQ割込みハンドラは\$C953から、IRQ割込みハンドラは\$D2FCからのようです。本カードにより(メインCPUを停止し)\$AAを書き込んだところ、以下のようになったため、\$FFE0~\$FFFDはRAM、\$FFFE~$\$FFFFはROMのようです。2019ArduinoとPCはUSBケーブルで接続し、それを通じてプログラムするのですが、そのケーブルを通じて通信することができます。IDEの機能であるシリアルモニターを立ち上げておけば、データを表示することができるので、これを利用します。IDEの機能であるシリアルプロッターという便利なものがあり、Arduino側でデータを出力すれば、IDE側でグラフをリアルタイムで書いてくれ、オートスケールまでしてくれます。面倒なのはArduino側で並列データの概念が無く、bitの入出力しかないため、アドレスのライトはbitに分解し、データのリードはbitを統合してやる必要があることです。以下にパラシリ、シリパラ変換を示します。1;}このコードの動作図を図157.1に示します。b;}このコードの動作図を図157.2に示します。2019設計編はこちらです。FusionPCBからベースボードが届きました。USD+配送料と、格安です。今回は製造に6.85日、DHLによる配送に3.34日かかりました。Proボード及び40pinコネクタの写真です。この他に動作確認用のLED及びそのドライバTr、抵抗があります。Proが975円、基板が上記のように522円、コネクタが(写真のコネクタではなく、純正のFCN-365P040-AU)が743円、合計2,240円でした。この他に配送料が若干かかっていますが、2つの目的である、FM7側にソフトウェアを置かないこと(FM7側にはファイルシステムが無いため管理できない)価格が安いことが達成できました。動作確認をするため、基本動作に無関係なLED等は未実装としています。2019IRQ/FIRQが正常動作したので、メインCPUとサブCPUの協調動作を実行してみます。協調動作フローチャートこのフローに基づき、協調動作のシミュレーションを行ったところ、正しく動作しました。2019タイムチャートを見直すと、例外処理中でEフラグをクリアする処理は入っていますが、一方のセット信号が初期状態からずっと不定です。このため、Eフラグが不定となっているようです。従って、セット信号を初期状態でネゲートします。割込みタイムチャートk_set_eの初期化をしたところ、正しく動作しました。このIPは総じて割込みの実装が中途半端にしかされておらず、割込みは実質テストしていないようです。プロセッサにおいて割込みが動作しないのは致命的であり、使い物になりません。2019次にFIRQを実装します。同様にFフラグセット、クリア論理を入れましたが、割込みハンドラまでは正しく動作するものの、RTI命令の実行時にスタックを過剰に回復しています。積んだ以上に回復するという、いわゆるスタックアンダーフローを起こしてしまいます。割込みタイムチャートまず、FIRQの動作を見てみると図153.2のようになります。Eフラグをクリアしてからpushすると書かれていますが、クリアされずXとなっています。次に、RTIの動作を見てみると図153.2のようになります。Eフラグは0であるべきなので、スタックからはCCR及びPCのみが回復されるはずです。タイムチャートではさらに他のレジスタも回復しているようです。RTIの動作この誤動作の原因は、CCR[7]のEフラグが不定となっていることです。従って、図153.2にあるとおり、例外処理中でEフラグをクリアする処理を入れれば動作するはずです。