Artix-7評価ボード>Artix-7技術コラム>DDR3-AXI-USBのサンプルデザイン

DDR3-AXI-USBのサンプルデザイン

VivadoでUSB3.0からAXIバスを経由してUSB3.0へ読み書きするサンプルデザインを作りました。

このサンプルデザインは次のような機能があります。

  • AXI-4を通じたMIG(DDR3メモリの読み書き)
  • シンプルなブロックRAMの読み書き
  • 640×480サイズの画像を想定したパターンジェネレータ
  • アドバンスドLEDチカチカ
  • GPIOの状態をUSB3.0に転送

なお、FX3からMIG(DDR3メモリ)への読み書きは、間にAXIインタコネクトを挟んでいるので、ここにユーザ回路を追加すれば、ユーザ回路からDDR3メモリに書き込み、それをUSBでパソコンに吸い上げるといった使い方ができます。

ダウンロード

 

FX3-AXIコア

このデザインで要になるのは、FX3-AXIコアです。

このコアは、EZ-USB FX3をAXIバスに変換するIPコアで、以下の機能を持ちます。

  1. USB3.0のBulk In/Outを標準的なAXI-4として出力する
  2. USB3.0のBulk In/OutをBRAMインタフェースとして出力する
  3. USB3.0のBulk In/Outを低レベルなローカルバスとして出力する
  4. Bulk In/Outで読み書き可能なローカルレジスタ(32bit×16本)の提供

ソースコードで提供されているので、VivadoでEdit in IP Packagerを行うとソースの編集ができます。

このコアは USBを使う のページのコアをAXIバス化したものです。こちらのページで紹介したUSB APIがそのまま使えます。

ポートの説明

  • usbというポートは、EZ-USB FX3へつながる信号です。Make ExternalでそのままFPGAの外に出してください。
  • M_AXIは、Full AXI-4のマスタです。ここにAXI Interconnectをつないで、MIGや、ユーザ回路をつないでください。
  • bramは、XILINXのbramインタフェースです。ローカルなBlockRAMをそのままつなげることができます。DDRメモリと比べて高速ですが、容量は最大512kバイト程度が実用的です。
  • bulkioは、特電仕様のローカルなバルク転送ポートです。各信号の使い方はこちらのページをご覧ください。
  • iregは、ローカルな内蔵レジスタ用ポートです。
  • clk100m_iは、元になるクロックです。reset_iは使用していませんが、平常動作時は'0'にしてください。
  • m_axi_aclkはMIGから出力されるui_clkを、m_axi_aresetnは、MIGから出力されるsync_rstを反転させたものを入れてください。

AXIと、BRAMと、内蔵レジスタの使い分け(プログラムの作成方法)

当コアを操作するPCのプログラムでは、基本的にはUSBWriteData、USBReadDataという関数を使います

int   USBWriteData(unsigned long addr,unsigned char *data,int len,unsigned short flag);
int   USBReadData(unsigned long addr,unsigned char *data,int len,unsigned short flag);

ここで、flag=0とすると内蔵レジスタ、flag=1とするとBRAM、flag=2とするとAXIバス(DDRメモリ)を読み書きします。

このサンプルデザインでは、flag=6とするとパターンジェネレータからの読み出しになります。

サンプルソフトについて

このサンプルソフトでは、内蔵BRAMや、DDRメモリ、パターンジェネレータへの読み書きができます。

FX3-AXIコアを通じて最大300MB/s超の速度で通信ができます。また、ソースコードも付属しています。

USB2.0でインタフェース USB3.0でインタフェース

 

内蔵レジスタ

内蔵レジスタは、32bitのシンプルなレジスタが16本集まったものです。

AXI-GPIOよりも手軽に、コントロール/ステータスレジスタが作れます。

VivadoのIPインテグレータでは、バスのバスが作れないので、512ビット幅の信号を作り、32×16のレジスタを詰めて出力しています。

内蔵レジスタへの書き込み

USBWriteData(レジスタ番号,data,4,0)で内蔵レジスタに書き込むと、
ireg_op[(レジスタ番号)×32+31 : (レジスタ番号)×32]
から、書き込まれた値が出てきます。

また、このとき、ireg_updated_op(レジスタ番号)が'1'になります。

内蔵レジスタからの読み出し

USBReadData(レジスタ番号,data,4,0)で、内蔵レジスタから読み出すと、

ireg_ip[(レジスタ番号)×32+31 : (レジスタ番号)×32]
のポートの値がPCから読み出せます。

また、このとき、ireg_captured_op(レジスタ番号)が'1'になります。

ブロックRAM

BRAMは、XILINXのブロックRAM用のポートです。

ここに標準的なブロックRAMを接続すると、USBWriteData(addr,data,len,1)で書き込み、USBReadData(addr,data,len,1)で読み出しができるようになります。

BRAMを使用しない場合は削除してしまって構いません。

 

 

BRAMを作るときには、以下のような設定にします。

  1. モードはStandAloneにする。実用的にするには、BRAMのもう一つのポートから読み書きしなければならないので、Single Port RAMではなくTrue Dualport RAMが良いだろう。

     
  2. 読み書きの幅は32bit。深さは任意。このサンプルでは131072になっているが、普通はこんなには必要ないだろう。
    Primitive Output RegisterとCore Output Registerのチェックは外すこと。そうしないと、読み出しが1クロック遅れるので、正しいデータが読み出せない。

     
  3. このページのオプションは変更不要。

     
  4. 全体の確認

 

パターンジェネレータ

パターンジェネレータは、640×480の大きさの様々なパターンを生成する回路です。

flag[2:0]=6としてUSBReadDataで読み出すとbulkinポートを通じてデータを送られます。

flagの[5:3]がパターンのタイプを決めています。このパターンジェネレータを試すには、サンプルソフトでIN data sourcePattern generatorにします。

Sequential Number

クロックでカウントアップしていく数字です。途中で飛ぶのは、USBの転送が連続ではないからです。

Horizontal gradation

水平グラデーションを生成します。

Vertical gradation

垂直グラデーションを生成します。

Frame Number

時間とともに明るさが変わります。

GPIO[31:0]、GPIO[63:32]

Artix-7ボードのGPIOの端子の状態をそのままデータバスにしたものです。

[31:0]は主に上側のピンヘッダ、[63:32]は主に下側のピンヘッダの値が読み出されます。

指で触るとノイズで縞模様が見えたりします。

Random Pattern

XorShift回路で作った乱数です。

 


© 2015 TokushuDenshiKairo Inc. All rights reserved