ロバストなマイクロコントローラとFPGAのSPIインターフェースの実装:パート3 - FPGAのトップレベルモジュール

APDahlen Applications Engineer

この回でも、マイクロコントローラ(uC)とフィールドプログラマブルゲートアレイ(FPGA)のインターフェースの探求を続けます。

  • Part 1では、より大規模なシステムの開発を導くVerilogの設計哲学を紹介しています。これは、クロック境界、ストローブの使用、ダブルバッファの必要性などのレジスタ転送レベル(RTL)の設計ガイドラインを紹介する重要な内容です。

  • Part 2ではSPIプロトコルについて説明しています。選択されたプロトコルは、可変ペイロード長や巡回冗長検査(CRC)などの概念を備えた802.3 Ethernetフレームを基にして、データの整合性を評価するものであることを思い出してください。

前回のハイライトは、図1に示しているコマンドと応答のフレームでした。コマンドフレームは、uCからFPGAに流れる情報のプロトコルを記述します。応答フレームは、FPGAからuCに流れるデータを記述します。このプロトコルはSPIを使用した全二重通信用に設計されていることを思い出してください。この要件には、FPGAハードウェアに関連するタイミングに細心の注意を払う必要があります。応答フレームは、コマンドフレームの受信時にリアルタイムで生成される必要があります。たとえば、uCがFPGAにデータ長のバイトを送信している間、FPGAは同時にユーザー定義のステータスフラグを送信します。同様に、uCがコマンドフレームのCRCを送信している間、FPGAは応答フレームのCRCを送信しています。

このリアルタイムストリーミング要件により、設計が複雑になります。そのため、この回ではトップレベルのFPGA実装をブロック図形式で説明することに専念します。今後の回では、ダブルバッファモジュールの詳細な分析から始めて、個々のFPGAブロックを詳しく掘り下げていきます。

図1: uCからFPGAへのSPIプロトコルの基礎を形成するコマンドフレームと応答フレーム

uCからFPGAへのデータ転送の俯瞰図

FPGAのハードウェアの概要を図2に示します。ハードウェアの動作をよりよく理解するために、右から左への概要から始めましょう。もし、まだお読みになっていないのであれば、システムレベルの設計に関連する課題のいくつかを指摘したパート1、特にダブルバッファに関するセクションを復習されるとよいでしょう。

右上にはパルス幅変調器(PWM)モジュールがあります。このモジュールが16ビットインターフェースを持っていることに注目することが重要です。同時に、図1に示すように、8ビットフォーマットを使用してSPI経由でデータが転送されることが暗黙の了解となっています。PWMが1バイトずつ更新されると予期せぬ動作が発生するため問題です。そうではなく、1クロックサイクルで16ビットすべてがPWMに入力されるように、16ビットすべてが同期して登録されなければなりません。

この同時更新はダブルバッファによって実行されます。このモジュールは、SPIハードウェアと、ブロック図の中央にある様々なバッファと制御モジュールからデータを受け取ります。ダブルバッファは、両方のバイトが受信されるまで待機し、同時にPWMを更新します。PWMモジュールは、次のPWMデューティサイクルの開始など、既知の開始位置で変更を実行します。

各ダブルバッファは、図3に示すように、バイト幅とアドレスを含む2つのパラメータでインスタンス化されます。バイト幅は、16ビットPWMや32ビットのダイレクトデジタルシンセサイザ(DDS)のような関連ハードウェアに合わせて選択されます。アドレスは図1のコマンドフレームに対応しています。例えば、PWMのデューティサイクルを設定する場合、代表的な最小コマンドフレームは、0x07、0x00、0x00、0x02、0x00、0xAA、0x55、0xFD、0x07です。この例では、アドレス0x0200にある16ビットPWMに0xAA55の値を書き込みます。この例では、読み取りアドレス(0x0000に設定)は重要ではありません。CRCモジュールについては今後の記事で取り上げる予定です。

図2: トップレベルFPGAのデータフローを示すブロック図

ブロック図を引き続き右から左へ移動すると、バッファによって供給されるメッセージライターと、SPIインターフェースによって供給されるCRCバリデータに遭遇します。メッセージライターエージェントは、終了フレームストローブとCRCバリデータによってトリガされます。このストローブは、図1に示すコマンドフレームが受信され、受信したCRCとCRCバリデータによって計算されたCRCを比較することによって検証されたことを示します。ダブルバッファライターは、アクティブ化されると、フレームバッファの内容を、PWM、DAC、DDSなどのさまざまなFPGAハードウェアモジュールに関連付けられたダブルバッファに転送します。

フレームバッファは、データ整合性検証プロセスの重要なコンポーネントです。まず、フレームバッファは、SPIインターフェースでストリームされるデータを収集します。同時に、CRCバリデータはストリームデータのCRCを計算します。図1に見られるように、CRCはフレームに付加されます。その結果、フレーム全体を受信するまで、CRCとフレーム検証の完全性は不明です。フレームバッファはCRCが完了するまでの時間を確保するために重要です。これにより、FPGAハードウェアがデータに作用する前にデータを検証できます。バッファによって、破損したフレームで行われた変更を元に戻す必要がなくなります。

図1と図2のフレームプロトコルが暗示するように、長さ、読み出し、書き込みアドレスフィールド、ペイロードは全てダブルバッファライターによって処理されます。CRCが検証されると、ダブルバッファライタは最初のペイロードバイトと共にベースアドレスを割り当てます。そして、ダブルバッファ内の最初のバイト幅のバッファをアクティブにする書き込みストローブが送られます。ダブルバッファライタはこのプロセスをN回繰り返し、次のデータに移ります。ここでNはフレーム長フィールドからヘッダフィールドの5バイトを引いたものです。このプロセスは、図3に示すようなダブルバッファの構造を調べることによって、よりよく理解することができます。

図3: ダブルバッファのブロック図

各ダブルバッファは、ベースアドレスと長さでインスタンス化されることを思い出してください。ダブルバッファには制御された動作シーケンスがあります。ダブルバッファ内のすべてのバイト幅のファーストステージバッファが満たされた後、ダブルバッファは自動的にセカンドステージに情報を転送します。この自動転送により、メッセージライターはダブルバッファの動作を制御する必要がなくなり、設計が簡単になります。その代わりに、フレームのペイロードを単に1バイトずつ連続して転送するだけでよいのです。

uCからFPGAへのデータ転送に移る前に、ダブルバッファライターの速度についてコメントします。図2のすべての項目は1つのクロックドメイン内で同期していることを思い出してください。CRCバリデータのストローブ受信後、ダブルバッファライターはFPGAの100MHzクロックのみに制限された速度でダブルバッファに書き込みます。その結果、100%フルフレームバッファは約5uSで読み出されます。

バッファは位置8’b05から8’bFFまで読み取られます。同時に、uCは、フレームバッファが空になると同時に別のフレームを開始して、それを埋める機能もあります。FPGAメッセージライターは、uCがバッファを埋めるよりも早くバッファを空にするため、干渉は問題になりません。このステートメントは、SPIモジュールがクワッドまたはオクタルSPIに置き換えられた場合でも当てはまります。

技術的なヒント: 皮肉なことに、この記事で説明したuCからFPGAへのインターフェースは、FPGAベースのソフトコアプロセッサの恩恵を受ける可能性があります。これには、FPGAファブリックに専用のuCをインスタンス化して、uCからFPGAへのインターフェースを実現する必要があります。XilinxのFPGAの場合、PicoBlazeのようなコントローラが適しています。この小さなステートマシンは、SPIモジュール、各種ダブルバッファ、およびそれらに関連するペリフェラル以外のすべてを置き換えることができます。アセンブラでコーディングする能力にもよりますが、それでもエレガントなソリューションになるでしょう。MicroBlazeのような従来のCプログラミングによる強力な選択肢もあります。XilinxのZynqを使えば、uCをFPGAに移すこともできます。同様のオプションは、ほとんどのFPGAプラットフォームで利用可能です。

FPGAからuCへのデータ転送の俯瞰図

この連載で説明するSPIインターフェースは全二重で、図1に示すように個別の読み出しアドレスと書き込みアドレスを送信できます。これはストリーミングプロセスであり、データがMOSIラインでFPGAにクロック同期で入力されると同時にMISOラインでuCにデータが送信されます。次に、右から左への信号フローを使用して、図2に示すRTLのFPGA送信プロセスを検証します。

このシリーズの第1回で説明したように、ダブルバッファプロセスは基本的な要件です。これは、図2の左下で示すエンティティに顕著に現れています。FPGAのセレクタスイッチ、16ビットDAC、ユーザー定義のステータスフラグ、エラーメッセージカウントがすべて登録されていることを確認してください。デー タは各SPI フ レームの開始時にキ ャ プチ ャ されます。この登録により、データ値がuCにストリームバックされる際に変更されないことが保証されます。これにより、マルチバイトデータの1バイトを更新する際の危険性が排除されます。

FPGAからuCにストリーミングされるデータはすべて、図2の右下に示すマルチプレクサ(mux)に送られます。muxの選択プロセスは、図1に示すように、コマンドフレームの読み出しアドレスに基づいて決定されます。SPIインターフェースがバイトをクロック入力すると、制御マシンはMUXを次の連続する読み出しアドレスに進めます。この動作により、独立した読み出し/書き込みアドレスを持つ全二重通信が可能になります。例えば、PWMへの書き込みと同時にFPGAのスライドスイッチを読み出すことができます。簡略化のため、図2のmuxは、暗黙のNバイト入力からバイト幅出力へと単純化されています。

図2のCRCバリデータには2つのインスタンスがあることに注意してください。前述したように、上のモジュールはuCからFPGAへのデータに関与し、下のモジュールはFPGAからuCへのデータストリームに関与します。

FPGAからuCへのデータのRTLに対して右から左へのデータフローの話を続けると、大きい方のmuxの出力がCRCバリデータに送られることがわかります。また、SPIインターフェース、最終的にはMISOラインに向かう途中で、より小さなmuxを通過します。CRCバリデータモジュールはストリームデータに対してCRCを構築することを思い出してください。小型のmuxにより、CRCはFPGAからuCへのメッセージに付加されます。この切り替え動作は、フレームバッファに保持されているNum_bytesをMSGリーダコントロールが理解することに基づいています。

Part 4 has been posted.

皆様のご意見やご提案をお待ちしております。高レベルのRTLシステム設計方法論に関するさらなる議論は特に歓迎いたします。

ご健闘をお祈りします。

APDahlen




オリジナル・ソース(English)