EZ-USB FX3とFPGAを接続するサンプルデザインを一新しています。
FPGAの中に入れるコアを下のようなモジュールにしました。
entity fx3sfsync is
Generic (
FX3_DATABUS_SIZE : integer := 32;
USR_DATABUS_SIZE : integer := 32
);
Port (
-- ezusb fx3 port
fx3_pclk_op : out std_logic;
fx3_data_bp : inout std_logic_vector(FX3_DATABUS_SIZE-1 downto 0);
fx3_flaga_ip : in std_logic;
fx3_flagb_ip : in std_logic;
fx3_sloe_op : out std_logic;
fx3_slrd_op : out std_logic;
fx3_slcs_op : out std_logic;
fx3_slwr_op : out std_logic;
fx3_addr_op : out std_logic_vector(1 downto 0);
fx3_pktend_op : out std_logic;
fx3_reset_bp : inout std_logic;
-- user interface port (mandantory)
clk100m_i : in std_logic;
reset_i : in std_logic; -- active high
bulkout_ready_i : in std_logic; -- not implement yet
bulkout_wait_i : in std_logic; -- User circuit is ready but nomore data cannot be received.
bulkout_start_o : out std_logic; -- Start timing of bulkout (SOF)
bulkout_busy_o : out std_logic; -- now running.
bulkout_end_o : out std_logic; -- End timing. (EOF)
bulkout_dvalid_o : out std_logic; -- Received data is valid
bulkout_data_o : out std_logic_vector(USR_DATABUS_SIZE-1 downto 0);
bulkin_ready_i : in std_logic; -- not implement yet
bulkin_start_o : out std_logic; -- Bulkin start (SOF)
bulkin_busy_o : out std_logic; -- now running.
bulkin_end_o : out std_logic; -- Bulkin end (EOF)
bulkin_data_i : in std_logic_vector(USR_DATABUS_SIZE-1 downto 0);
bulkin_dreq_o : out std_logic; -- Bulkin data request
bulkin_dvalid_i : in std_logic; -- Send data is valid
bulkin_abort_i : in std_logic; -- Abort and send PKTEND
datalen_o : out std_logic_vector(31 downto 0);
addr_o : out std_logic_vector(31 downto 0);
flag_o : out std_logic_vector(15 downto 0);
debug_o : out std_logic_vector(31 downto 0) -- for debug
);
end fx3sfsync;
これじゃわかりにくいので、図にしました。
fx3_*で始まるポートはFX3にそのまま繋ぎます。bulkout_*で始まるポートはBulkOutのときに使い、bulkin_*で始まるポートはBulkOutのときに使います。
動作を簡単に説明すると、BulkOUTのときには、bulkout_startが1クロックアサートされて、PCからBulkOutが発生したことを知らせます。そして、bulkout_dvalidがアサートされている間は、何かしらのデータが送られてきていることを示しています。
簡単でしょ?
ただ、このままだとユーザ回路の準備が整っていないのにデータが送られてきてしまう可能性があるので、bulkout_waitという信号を用意しています。ユーザ回路がこの信号をアサートすると、コアはデータの出力を止めます。
ただ、バースト転送は急には止められないので、waitをかけても数個分のデータが出てきてしまいます。
BulkINのときには、bulkin_start_oが1クロックアサートされて、PCからBulkIn要求が発生したことを知らせます。ユーザ回路は、bulkin_dreq_oがアサートされているのを見たら、bulkin_dvalidと共にデータを送ります。
もし、FX3が「データをこれ以上送らないでほしい」(つまりFX3内のバッファがFULL)と言っているときには、bulkin_dreq_oが下がるので、ユーザ回路はデータの送信を止めます。
それから、ユーザ回路側の都合でデータ送信を一旦停止したい場合は、bulkin_dvalidを下げるだけで良いので簡単です。下の図ではランダムなタイミングでWAITをかけています。
このような簡単なハンドシェイク型のインタフェースで、EZ-USB FX3と通信ができるようになりました。
パソコン側のAPIは、
int USBWriteData(unsigned long addr,unsigned char *data,int len,unsigned short flag)
int USBReadData(unsigned unsigned long addr,char *data,int len,unsigned short flag)
という2つの関数を用意しています。転送したいデータが格納されたバッファと転送長、それからオプションのデータ(addrとflag)を指定してこの関数を呼び出せば、FPGA内で上の動作が起こります。
転送速度なのですが、普通のパソコンのPCI Express拡張スロットにUSB3.0拡張ボードを接続してつないだ場合は、OUT 111MB/sec、IN 155MB/secくらいでした。
これはおそらくPCI Expressの部分の速度がボトルネックになっていると感じたので、マザーボードから直接USB3.0が生えている比較的最新のPCでやってみたら・・、
OUT 255MB/sec、IN 367MB/secと、満足がいく速度が出ました。
これで、EZ-USB FX3が本当にEasyに使えるようになりました。
次はSpartan-6のMCBとつないでDDR2/DDR3 SDRAMの中のデータをUSB3.0経由で読み書きできるようにしたいと思います。
このサンプルデザイン(FPGAのデータ、GPIF II Designerのデータ、ファームウェア、PCのソフトウェア)は、下記のリンクからダウンロードできるようにしました。
● fx3sample-20130521.zip をダウンロード (8.9MB)
ただ、まだドキュメントがありません。ドキュメントの体裁を整えるために1日~2日必要です。もし、すぐに使ってみたいという方はメールください。
【広告】
特電のEZ-USB FX3ボードは下記のリンクからお買い求めいただけます。現在の在庫は残り2台ですので、お早めに!
https://shop.tokudenkairo.co.jp/shopping/detail.php?shpdi=TKDNFX3
最近のコメント