VME プロトコル

プリスケーラーロジックを実装して遊んでいると、いちいちコンパイルし直さずにパラメータを変更したいと思うようになると思います。 その要求を VME を用いて実現します。 書き込みなどの制御信号は CPLD で判定しているので、気になる人は CPLD の Verilog コードと VME インターフェースの説明をよんでください。 VME バス規格自体の詳しい説明は避けます。 いくつかの FPGA 制御信号とアドレス・データに絞って考えることにします。

多くの高エネルギー実験で VME 規格で作成したボードを使用しています。 しかし、VME バスでは要求するデータ幅に対応出来ないことが多いので、今回のようにパラメータを変更する用途などに使用していることが多いようです。

Read タイミング

VME からしたら通信を行っている相手が FPGA ということは知りようがありません。 FPGA/CPLD も含めて、一般にメモリに対する書き込みのタイミングを下図に示します。

この例では 0x1234 というアドレスから読みだしたデータが 0xabcd であったことを意味しています。 以下で具体的に説明します。

最初に読み出したいアドレス (ここでは 0x1234) を VME から制御します。 そのアドレスのデータを読み出すために CPLD から制御信号を操作していきます。 まず Chip Enable をアサート(有効に)します。 VME バス上に複数の FPGA がのっていることも多くあります。 それらの FPGA が同時に反応してしまうと、バス内で信号の衝突が起きます。 それを防ぐために、どのチップとやりとりをするのか選択するのが CE の主な役割です。

Chip Enable がアサートされた状態になると、次に Output Enable をアサートします。 Read/Write のどっちの操作を行うのかを指定するために Output Enable/Write Enable があります。 今は Read をしたいので、 Output Enable をアサートしましょう。 これらの操作を行うことで、読みたいアドレスに対応するレジスタ(値を保持する箱)に入っているデータを読み出せます。 読み出しが終われば、CPLD から配られる CE, OE を元に戻すことを忘れないようにしましょう。

ここと次の Write タイミングで説明するのは一般のメモリに対して成り立つことです。 ピンの名前が違ったり、より高度な操作を行うために追加の信号が必要だったりすることがありますが、基本を理解しておくことが重要です。

Write タイミング

Write も、似たようなものです。同じようにタイミングチャートを載せます。

さきほどの説明でだいたい同じように理解できますよね。 チップを選択し、 Write Enable 状態にします。 その上で、書き込みたいアドレスに対してデータを書き込みます。

繰り返し言っておきますが、FPGA に対して読み書き操作を行う説明ですが、この説明は多くのメモリに共通する内容です。 見慣れない種類のメモリ ( SPI, BPI, … ) で合ったとしても、この基本は変わりません。 チップの説明書(データシート)から細かい変更点を読み取るだけで、対応が可能です。

VME を用いた読み書き

さて、では実際に VME から読み書きしていきましょう。 VME のコントローラとしては本当に実験で使用する時は Single Board Computer を使用するかもしれませんが、実験室などでテストを行う際には SBS 社の Bit3 を使用することが多いようです。 Bit3 を使用するためのドライバーについては vmedrv を使用していること前提で話を進めていきます。

特定のボードを操作するには専用のソフトウェアを書いたりするのですが、ここでは vmedrv に付属している vmeget/vmeput を使用して読み書きしてみましょう。 私が管理している PC であれば vmedrv はここにあります。

$ cd /local/vmedrv

この下に version ごとに directory を作っておくようにしています。

まずは、ある 0x12345678 というアドレスの値を読んでみましょう。

$ cd /local/vmedrv/ver121
$ ./vmeget /dev/vmedrv32d32 0x12345678

というようにします。 今回の場合 アドレス 32 bit、データ 32 bit のボードにアクセスするつもりで vmedrv(a)32d32 というデバイスを選択しています。 その次に続く引数が読みに行くアドレスです。 簡単ですね。

同じように 0x12345678 に対して 0xabcdabcd という値を書き込むには次のようにします。

$ ./vmeput /dev/vmedrv32d32 0x12345678 0xabcdabcd

今は説明のために適当なアドレスを指定していますが、これを実際に読み書きしたいアドレスに置き換えれば実際に操作することができます。

PT6 の VME 操作

では、実際に先ほど作った Prescaler ロジックのファクターを VME から操作してみましょう。

先ほどのファームウェアでは Prescaler ロジック一つでしたが、そこに VME Read/Write 操作を司る VMEEncoder モジュールというのを追加してみましょう。 追加後のブロック図は次のような感じです。

VMEEncoder モジュールを追加し、VMEEncoder モジュールと Prescaler ロジックとの間で fact という値を受渡しています。 こうすることで、いちいち bitfile を作り直す必要がなくなり、VME から ( 実際に操作するのは PC ) Prescale factor を変更することが可能です。 ここでは VME から操作するのは 1 つの値だけですが、通常複数(数十、数百)の値を設定出来るようなデザインが普通です。

VME プロトコルを判断し、FPGA に Chip Enable などの信号を送っているのは CPLD です。 CPLD は不揮発性(電源を切った後も書き込んだファームウェアが残る)ので、通信制御などを行うためにボードに載せています。

必要なコードはここにあります。svn url もしくは svn からとってくるには

 svn co svn+ssh://$USERNAME@svn.cern.ch/reps/atlas-tkunigo/tkunigo/software/testbench/Bit3/pt6/FPGA/PT6_VMEEncoder

です。

コードの基本的な見方は最初に詳しく説明したので、今は省略します。(あまりにも分からないようなら、後に追記します。) VMEEncoder モジュールでは、上で示したタイミングチャートに合わせて、VME のアドレスを見て、 Prescale factor レジスターの値の読み書きを行っています。

出来上がる bitfile を FPGA に書き込み、その後実際に fact を読み書きしてみましょう。 どこのアドレスに書き込めばいいのかを知るには PT6 のアドレス空間を知る必要があります。 下にアドレス空間の表を書いておきます。

アドレス 31 - 20 19,18 17 - 11 10 9 - 2 1, 0
FPGA ボードアドレス 00 not used 1 offset Byte access
CPLD ボードアドレス 00 not used 0 offset Byte access

* 実際に FPGA にやってくる ( VMEEncoder でしている )アドレスは offset 部分です。

  • ボードアドレスは、同じクレート内でアドレスが被らないようにボード上の DIP SW で指定しています。

ボードアドレスを 0x0f1 だとした時、VMEEncoder モジュール内で Prescale factor に対して定めているアドレス 0xf0 にアクセスするためには 0x0f1007c0 というアドレスにアクセスすればよいことが分かります。 本当かどうか vmeget で確かめてみましょう。 正しく読めれば、初期値の 10 ( = 0xa ) が返ってきます。 その後、好きな値に書き換えて遊んでみてください。

ここまで出来れば、結構色んなことが出来るようになります。 値を自由自在に書き換えられれば、色んなボードの設定を変更することが可能です。

上の例で何となく分かると思いますが、ボードを操作する上でアドレスの定義が非常に重要です。 ボードをデザインすることがあれば、どこにどれだけのアドレス空間を割り振るのか、また同じクレートに存在するボードとアドレスを衝突させないようにするにはどうしたらいいのか、というのに頭をひねる必要があります。
testbench/introduction_to_verilog_hdl/vme_encoder.txt · 最終更新: 2019/02/15 09:07 (外部編集)
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0