IPコアのレジスタインターフェースについて

出典: Wikimura

目次

IPIF

FPGAでCPUコアを搭載し、バスに自分の作ったハードをつなぐ場合、IPIF(Xilinx)を作る必要がある。

バスに直接IPをつなぐのは、バスの仕様を知らなくてはならないため難しい。 そのためXilinxでは、バスにつなぐ部分を提供してくれる。

バスにつなぐためのIPは、割と簡単なインターフェースを提供してくれる。 開発者は、このインターフェースと自作のIPをつなぐ回路を作ることで、バスにIPをつなげるようになっている。

|||                 +--- ここを作る               
|||                 |
|||   +------+   □□□   +----+
|||   |      |   □□□   |    |
|||===|Bus IF|===□□□===| IP |
|||   |      |   □□□   |    |
|||   +------+   □□□   +----+
|||
Bus

IPIFとのやりとり

CPUからは、ペリフェラルがメモリにマップされて見える(ものがある)。

IPIFは、自身のマップされたアドレスへのアクセスがあると、以下のようなやり取りを行うようになっている。 (受動態はIPがBusIFからされること。能動態はIPがBusIFに対して行うこと)

  • ライト
    • アドレスバスに書き込み先がセットされる
    • データバスにデータがセットされる
    • 有効範囲が示される(何ビットから何ビットが有効)
    • ストローブ信号がアサートされる(その信号のタイミングでデータを格納すること)
  • リード
    • アドレスバスに読み込み先をセットする
    • データバスへデータをセットする
    • 有効範囲を示す
    • ストローブ信号をアサートする

インターフェース

バスとのやりとりを直接IPが行えるかと言うとそうではない。 IPは独自の制御形式を持つ場合がある。


例えば以下のようなハンドシェイクがある。

  • 処理が受け付けられるまでリクエスト信号をアサートし続けなくてはならない
  • 受けつけられたらAckがアサートされる
  • Ackを受け取ったらリクエストをネゲートすること


BusIFはこのような複雑なことはできない。CPUを待たせることもできない。 だからといって、ユーザIPはBusIFに合わせてインターフェースを作るわけにはいかない。 そのため、これらを結ぶロジックを作る必要がある。


インターフェースの例

IPとBusIFとのインターフェースは、簡単なものであればステートマシンなどを使わなくてもできる。 (普通はレジスタに対して書き込むのはCPUかIPのどちらかだけ)

  • Readは衝突なくできる
  • Writeはどちらか一方(工夫すればできなくないだろうが、必要かは不明)
  • Set/Clearはどちらからでも、Writeと衝突なくできる

以下のようなやり方がある。

パラメータなど

USARTの通信速度や、モータの角度など、処理のパラメータ設定はCPUが一方的にやるもの。 こういったインターフェースは以下のようなレジスタで実現できる。

IPは設定された値を読むだけ。 CPUはレジスタに読み書きできる。

      Read  <------------+
                         |
                +-----+  |
Bus   Write >---|D   Q|--+---> IP
                +--^--+
                   |
      Strobe ------+

ステータスなど

統計データやセンサデータなどは、IPが出力するのみ。 出力は直接Busのデータへ入れてもOK。(もちろんアドレスが選択されたら)

Bus <-----< IP


リクエストなど

USARTなどでは送信開始をレジスタで行えるようになっている。 レジスタへの書き込みがあったら、Req信号をアサートするような回路にすれば、 簡単なハンドシェイクがレジスタで作れる。

        Req -------+             
                   |             
                +--+--+          
                | Set |          
                |     |          
CPU   Read <----|D    |       IP
                |     |          
                | Rst |          
                +--+--+          
                   |             
                   +-------< Ack 

もっと進んだインターフェース?

USARTのデータレジスタにデータを書き込むと、自動的に送信開始されるタイプのマイコンがある。 こういったものは、IPとバスIFの間を少し複雑にすれば実現できるはず。


バスの実現方法

よくバスと言うと、トライステートバッファで描かれていることがある。 VHDLで外部の回路とつなぐ部分を記述する場合は、トライステートバッファを使ってもかまわない。

しかし、FPGA内部でバスを作る場合、トライステートバッファは使えない(はず)。 というのも、FPGA内部にトライステートはないため。

代わりに使われるのがANDとORを使ったバス。(うろ覚え)

     __________________
    | Address Decoder  |
    |__________________|
       |  |  |  |  |   _____
A ----AND |  |  |  | --|    |
B -------AND |  |  | --|    |
C ----------AND |  | --| OR |----
D -------------AND | --|    |
E ----------------AND--|____|

AからDはデータバスに乗せる信号。これらは全てアドレスデコーダの出力とANDを取られている。 選択された信号だけが非0となる。 これらの信号は全てビット毎にORされる。 アドレスデコーダは常に1つだけ'1'にするため、ORを取ったものはAからEのいずれかになる。

こうして実装されるため、バスを使うようになるとかなりリソースが消費されてしまう...