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のいずれかになる。
こうして実装されるため、バスを使うようになるとかなりリソースが消費されてしまう...

