COJTのハードさが浮き彫りに

 冒頭で述べたように、実システムで自ら設計した回路を動かすのは今回が初めてです。第1段階で実システムとしてもきちんと設計した回路が動作し、色のパターンがディスプレーに表示されているのを見ると、やはり感慨深いものがありました。

 しかし、まだ表示回路の第1段階が終わったにすぎません。今のままでは“回路内で生成した画素情報を表示するだけ”のディスプレー表示回路です。第2段階を終えてやっと本当の表示回路が完成となるのですが、この第2段階からCOJTのハードさが少しずつ浮き彫りになっていきます。

 第1段階では、ディスプレーの画像表示期間にあらかじめ決められたパターンの画素情報を転送する回路を設計しました。しかし、一般のディスプレーが表示する画像は、元をたどればパソコンなど何らかのシステムの主記憶上に格納されたデータです。従って、表示回路として機能するためには、このデータにアクセスし、フレームの情報を取り出して、それをディスプレーに転送し、表示することまでができなければなりません。一連の手順をすべて回路上で実現して、初めて今回の課題である表示回路の完成といえます。

 第2段階では、まずFPGA上のメモリーに格納されたフレーム情報をFIFOに転送する回路を設計します。今回の表示回路に限らず、これ以降の課題はすべて主記憶へのアクセスを伴う回路を設計するのですが、その際に気を付けなければならないことがあります。それは、アクセスを“調停”する仕組みです。

 主記憶は、データを読み込まれることもあれば、書き込まれることもあります。そこで例えば、メモリーへの読み込み信号と書き込み信号が一斉に出ると、混信が発生して、データの受け渡しがうまくいかない恐れがあります。従って、何らかの方法でメモリーへのアクセスを調停する仕組みが必要になるのです。

 今回その役割を担うのが、「AXIバス」と呼ばれる機構です。先に述べたように、表示回路以降の課題ではすべてメモリーへのアクセスを伴うので、このAXIバスが重要な役割を担います。

 一般に、メモリーアクセスの調停を個人で実装する場合、そのために設計者が構築する論理は複雑になりがちなのです。AXIバスを用いると、データの受け渡しを行う回路は、送るデータが有効であることを確認する「VALID」と、データを受け取る準備ができたという合図である「READY」という2種類の信号をAXIバスとやりとりするだけで、メモリーに情報を伝達できるのです。すなわち、この2種類の信号さえきちんと制御していれば、そこから先のメモリーへのアクセスはAXIバスがすべて受け持ってくれるという、かなり便利な機構なのです。

 この際のアクセスの手順ですが、主記憶にはアドレスという実世界でいう住所に相当するものがあり、すべてのアドレスには1対1でひも付いているデータの格納場所があります。第2段階で最初に設計する「メモリー制御回路」では、画像が格納されている場所のアドレスを発行し、きちんと発行できたことを確認した後、そのアドレスに対応する格納場所から画素のデータを読み込むということを、AXIバスを介して繰り返し行います。読み込んだ画素のデータはFIFOに格納し、第1段階で作成した同期信号生成回路の期間有効信号に合わせてディスプレーに転送します。

 一見大したことはやっていないように思えるかもしれませんが、突然現れたAXIバスという機構の動作を理解し、正しく動作するように回路を記述することは大変で、私も講師の説明を聞いただけでは実装できませんでした。特に、AXIバスとのVALID/READY信号のやり取りでは幾つかの約束事を守らないと、互いに信号を待ち続ける「デッドロック」という状態に陥って回路の動作が停止する恐れがあるので、そうならないような回路記述を考えるのに苦労しました。

 主記憶のアドレスを発行し、そこから画素のデータを読み込んでFIFOで転送するという一連の処理では、1つでもアドレスを間違えたり、画素のデータがFIFOに読み込まれなかったりすると、正しい画像を表示できません。期間有効信号が来ていない間は、FIFOに画素がどんどんたまっていき、放っておくとFIFOが満杯になって読み込んだ画素をFIFOに格納し切れなくなるので、そのようなことが起きないように画素の読み込みを一時的に停止する、といった動作も必要となります。回路の規模が大きくなるにつれ、面倒を見ないといけない部分が増えるので大変でした。