シフトレジスタで作るSPI

シフトレジスタで作るSPI

 SPIというのはSerial Peripheral Interfaceの略で、デジタル回路の中でインタフェースの部類に入ります。FPGAの中で使うことはあまりありませんが、FPGAと何かを接続する際に多用します。

 似たようなシリアルインタフェースにUART(Universal Asynchronous Receiver Transmitter)やI2C(Inter-Integrated Circuit)があります。

 UARTは主にCPUで使用しますが、非同期通信です。FPGAとUARTの相性はあまり良くありません。きちんと設計すれば問題ありませんが、非同期通信ゆえ、同期化の部分でデータを取りこぼす等の不具合が発生することが多いので、設計は少し難しい部類に入ります。

 I2CはSPIに並んで多用されるインタフェースで、これもFPGAの中では使用しません。SPIと同様にFPGAと外部のインタフェースとして使います。たとえば、デジタル信号をアナログに変換するDAコンバータや、アナログ信号をデジタルに変換するADコンバータ等がSPIやI2Cで扱う事の多いデバイスとして挙げることができます。

 SPIはシフトレジスタを使った回路の中でも使用頻度が高く、設計は比較的簡単なので本ブログで取り上げることにしました。

 しかし、現在のFPGAは各メーカーが提供している統合開発環境を使って設計すると思われますので、その中にSPIはIP(Intellectual Property)としてあらかじめ搭載されている事でしょう。しかも、各メーカーのSPIのIPは無償だと思います。なので、わざわざ自分で設計することは無いと思います。

 したがって、本ブログでもVHDLやVerilogでの設計をしません。IPを使うにあたってSPIの動作やモードなどを知り、IPを使う際のオプションを設定できるようになるのが目的です。

 解説にあたり、何か具体的なターゲットがあった方が良いので、秋月電子で手に入るADコンバータでSPIインタフェースの物を探してみました。MicroChip社のMCP3002を使って解説していきます。

 MCP3002のデータシートはココにリンクしておきます。

  まず、FPGAとMCP3002の接続方法を示します。

 MCP3002のデータシートに合わせた信号名にしてあります。実際にMCP3002をFPGAに接続する際には、各信号の電圧を確認しておいてください。

 FPAGのIOの電圧には設定できる種類があります。それに、MCP3002の電源電圧によって、MCP3002の各信号ピンの電圧が決まります。

 FPGA側の信号名ですが、これはIPの信号名ではありません。自分でSPIを作ると想定して信号名を付けました。なので、使うFPGAのメーカーによってIPの信号名が違うかも知れません。これから述べる信号の意味を理解してIPの信号名に置き換えて設計してください。

  • nCS   チップセレクト信号。負論理。
  • SCLK  シリアルクロック。
  • MOSI  データ出力。
  • MISO  データ入力。

 SPIの接続において、接続元となるマスタと接続子となるスレーブという呼び方があります。一般的にはFPGAはマスタになる事が多いと思います。FPGAがスレーブとなる場合はCPUなどがFPGAの他にあって、CPUがマスタになって、FPGAがスレーブとなる場合です。

 IPを使う際に、「マスタモード」なのか「スレーブモード」なのかを選択しますが、接続する物がCPU以外の場合を除いてほとんどFPGAがマスタです。もちろん、例外もありますので、接続するデバイスに合わせてください。

nCS

 チップセレクト信号です。信号はマスタ->スレーブの接続になります。もしかすると、FPGAのSPI-IPの中にこの信号が無いかも知れません。無い場合には自分で作る。という事になります。

 チップセレクト信号は通常は負論理です。デバイスでデータシートで確認してください。MCP3002は負論理でした。

 FPGAの場合、VHDLやVerilogで設計しますので、テキストで記述します。なので、負論理を示す文字の上の—を記述できません。したがって、一般的には負論理信号をVHDLやVerilogで記述するときに、信号名の頭に’n’を付けます。なので、このチップセレクト信号も負論理なのでnCSという名称になっています。
(’n’ではなく、’/’を付ける人もいます)

 チップセレクト信号はスレーブデバイス1個に1本を割り当てるようにします。回路図では以下のようになります。

 このように接続することで、1つのSPIインタフェースで何個かのスレーブをコントロールすることができます。このような接続を「数珠繋ぎ(じゅずつなぎ)」とか「シリアル接続」と呼びます。現場の会話では「数珠繋ぎ」の方が多いかも知れません。

 1個のマスタで複数のスレーブをコントロールするので、対象となるスレーブの時にチップセレクト(nCS)をLowにします。スレーブ側はチップセレクトがLowになった時に、”自分が操作されてる!”と判断して動作します。

 自分で作る。と言いましたが、DFFを使ってSPIのIPにスタート信号を出す前にチップセレクト信号をLowにすれば良いだけです。初期値をHiにしておくのを忘れないようにしてください。

SCLK

 シリアルクロックです。シリアルクロックは立ち上がりエッジを使う場合と立下りエッジを使う場合があります。多いのは立ち上がりエッジです。これは使うスレーブ側に合わせてください。注意が必要なのは、スレーブによってシリアルクロックの周波数がある範囲で決められている事です。

 MCP3002の場合はデータシートから電圧5Vで使用する場合は、3.2MHzです。ここでFPGAのクロックが3.2MHzであれば問題ないのですが、一般的にはそんなに遅い事は無いでしょう。SPIのIPではクロックの分周器が内蔵されている物もあるので、その場合には分周比を設定します。

 内蔵されていない場合には自分でクロックを作る必要があります。分周して作るのですが、なるべくデューティーが50%になるようにしましょう。

 スレーブのデータシートを読んでいると、クロックの解説の中にmodeという言葉が出てくることがあります。これはクロックとデータのエッジか位相関係を記した事なのですが、規格で決まったことでは無いようなので、各社の書き方が統一されているとは限りません。したがって、modeという言葉だけでエッジや位相を決めるのではなく、その内容がどうなっているのかをデータシートで確認するようにしてください。

 スレーブが何個か接続される数珠繋ぎの場合、SCLKは各々に同じ信号を接続します。

 この場合、ハードウェアのエンジニアとして、常識的には「一筆書き」でクロック信号をスレーブデバイスに接続します。FPGAから近いスレーブアドレス順にSCLK信号を接続します。

MOSI

 MOSIって変な名前です。現場で「エムオーエスアイ」と呼ぶ人いますね。私はわざと「SPIのモシ信号」と読んでいます。お客様にも「モシ信号」で伝わっているようなのですが、何が正解かわかりません。Master Out Slave Inの頭文字を取ってMOSIです。データの流れる方向を示しています。マスターから出力して、スレーブに入力する。という意味ですね。

 1ビットのデータ信号です。この信号こそがシフトレジスタで作成されています。MCP3002の場合16ビットのシフトレジスタで構成されると思います。

 MCP3002のデータシートを読んでいて、困ったことになると思います。FPGAのSPI-IPは8ビット単位でしか設計できないのに、MOSIが5ビット指定されています。このように変なビット数を要求するスレーブデバイスは多いです。しかし、一般的にSPIは8ビット単位でマスタが設計されているのはスレーブのデバイスメーカもわかっていますので、必ず8ビット単位でコントロールできるように「余白」を残しているはずです。データシートを良く読んでください。

 MCP3002の場合には16ビットアクセスの方法がきちんと記されています。このように親切なデバイスばかりでは無いのですが、その場合には必ずDon’t careとなっている部分がありますので、そこを上手く利用して8ビット単位にしてください。

MISO

 「モシ信号」と来たから、「ミソ信号」です。Master In Slave Out。マスターが入力で、スレーブが出力。という意味ですね。

  この信号も各スレーブからの信号を1本にまとめてマスタに接続します。ただし、デバイスはチップセレクトされていない時(つまり、動作していない時)には、DOUTの信号を入インピーダンスにする物が多いです。MCP3002の場合にはDOUTの信号を出力しない時にハイインピーダンスにします。

 このハイインピーダンスというのは、MISO信号をワイヤード・オアするためなのですが、時に悪さをすることがあります。

 一般的にハイインピーダンス状態のプリント基板パターンというのは何も接続されていない状態と同じと考えられます。何も接続されていない金属(=プリント基板のパターン)はノイズの発生源になる事があります。

 それを防ぐために、MISO信号を軽くプルダウンしておくことをお勧めします。

 たとえばこのような感じで100kΩ程度でプルダウンしておくと、DOUT->MISOのプリントパターンがハイインピーダンスになった時でも、「何も接続されていない金属」にはならないので、ノイズを抑える事ができます。