FTDI社のUSB3.0ブリッジIC FT600の転送レートをEDA-009を用いて実際に計測しました。
EDA-009はALTERA社のCycloneVとFT600をクレジットカードサイズのボードに搭載したFPGAボードです。
転送レートの理論値はデータ16bit幅・100MHz動作という仕様から、200MB/s (MByte/sec 以下同様)となっています。
アプリケーションで計測を行った結果、下記のようになりました。
- 送信:約195MB/s
- 受信:約180MB/s
計測の詳細については下記を参照してください。
設定
以下の設定で測定を行いました。
- FT600の動作モード:245 FIFO, 100MHz
- 測定範囲:0.1MB(104858 Byte)~50MB を0.1MB刻みで500点
- 測定回数:100回を平均
- D3XXデバイスドライババージョン:v1.1.0.0
- 実験ボード:EDA-009
送信
FT600からFPGAへデータを送信し、ステータスが送信完了となるまでの時間を測定します。FPGAではデータは読み捨てています。
アプリケーションの送信プログラムは下記のようにしました。
OVERLAPPED vOverlappedWrite = {0};
vOverlappedWrite.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
ftStatus = FT_WritePipe(ftHandle, 0x02, buff, bytesToWrite, &bytesTransferred, &vOverlappedWrite);
if (ftStatus == FT_IO_PENDING)
{
// Poll until all data requested ulBytesToWrite is sent
do
{
// FT_GetOverlappedResult will return FT_IO_INCOMPLETE if not yet finish
ftStatus = FT_GetOverlappedResult(ftHandle, &vOverlappedWrite, &bytesTransferred, FALSE);
if (ftStatus == FT_IO_INCOMPLETE)
{
//AddReport(String().sprintf(_T("FT_IO_INCOMPLETE (%d)"), num_incomp));
AttachReport(".");
num_incomp++;
continue;
}
else if(ftStatus != FT_OK)
{
AddReport(String().sprintf(_T("WritePipeAsync()::FT_GetOverlappedResult. (0x%X)"), ftStatus));
CloseHandle(vOverlappedWrite.hEvent);
return -1;
}
else //if (ftStatus == FT_OK)
{
break;
}
}
while (1);
}
CloseHandle(vOverlappedWrite.hEvent);
FPGAの受信ステートマシンは下記のようにしました。clkは200MHzです。(FIFOへの書込等が含まれています)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity H_FT600_S245_RX_V3 is
port
(
clk : in std_logic;
reset : in std_logic;
act : in std_logic;
rcv_cmp : out std_logic;
rcv_length : out std_logic_vector(15 downto 0);
fifo_data : out std_logic_vector(15 downto 0);
fifo_wrreq : out std_logic;
be : in std_logic_vector(1 downto 0);
rxf : in std_logic;
oe : out std_logic;
rd : out std_logic;
data : in std_logic_vector(15 downto 0)
);
end entity;
architecture rtl of H_FT600_S245_RX_V3 is
-- Build an enumerated type for the state machine
type state_type is (idle,s0,s1,s2,s3,s4,s5,s6,t0,t1,e0,e1);
signal state : state_type;
signal rcv_length_reg : std_logic_vector(15 downto 0);
signal rxf_r : std_logic;
signal oe_r : std_logic;
signal rd_r : std_logic;
begin
rcv_length <= rcv_length_reg;
process (clk, reset, rxf, act)
begin
if reset = '1' then
state <= idle;
oe <= '1';
rd <= '1';
rcv_cmp <= '0';
rcv_length_reg <= X"0000";
oe_r <= '1';
rd_r <= '1';
fifo_wrreq <= '0';
elsif (rising_edge(clk)) then
rxf_r <= rxf;
oe <= oe_r;
rd <= rd_r;
case state is
when idle =>
rcv_length_reg <= X"0000";
rcv_cmp <= '0';
fifo_data <= X"BEEF";
fifo_wrreq <= '0';
oe_r <= '1';
rd_r <= '1';
if rxf_r = '0' and act = '1' then
state <= s0;
else
state <= idle;
end if;
when s0 =>
state <= s1;
when s1 =>
state <= s2;
when s2 =>
oe_r <= '0';
state <= s3;
when s3 =>
state <= s4;
when s4 =>
rd_r <= '0';
state <= s5;
when s5 =>
state <= s6;
when s6 =>
state <= t0;
---------------------------------------
when t0 =>
if rxf_r = '0' then
fifo_data <= data;
fifo_wrreq <= '1';
oe_r <= '0';
rd_r <= '0';
rcv_length_reg <= rcv_length_reg + 1;
state <= t1;
else
fifo_data <= X"DEAD";
fifo_wrreq <= '0';
oe_r <= '1';
rd_r <= '1';
rcv_length_reg <= rcv_length_reg;
state <= e0;
end if;
when t1 =>
state <= t0;
---------------------------------------
when e0 =>
rcv_cmp <= '1';
state <= e1;
when e1 =>
rcv_cmp <= '0';
state <= idle;
end case;
end if;
end process;
end rtl;
送信レートの観測結果をグラフ化したものが下記になります。約195MBに近づいています。

ある一定量のデータが出力されると出力が一時中断します(RXFが上がる)。今回の観測では0x200, 0x400, 0x600 または 0x800 Wordsで中断が発生しました。
0x200 Words以下では中断しませんでした。これはFT600内部の出力バッファサイズと一致します。
中断時間は16~2186 clockとまちまちでした。
SignalTapでの観測波形

クリックで全体を表示
受信
アプリケーションからの受信開始を受けてFPGAからFT600へデータを送信し、ステータスが受信完了となるまでの時間を測定します。
アプリケーションの受信プログラムは下記のようにしました。
overlappedRead.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
if(FT_InitializeOverlapped(ftHandle, &overlappedRead) == FT_OK)
{
ftStatus = FT_ReadPipe(ftHandle, 0x82, buff, bytesToRead, &bytesRead, &overlappedRead);
if(ftStatus == FT_IO_PENDING){
while(1){
ftStatus = FT_GetOverlappedResult(ftHandle, &overlappedRead, &bytesRead, FALSE);
if(ftStatus == FT_IO_INCOMPLETE){
//AddReport(String().sprintf(_T("FT_IO_INCOMPLETE (%d)"), num_incomp));
AttachReport(".");
num_incomp++;
continue;
}else if(ftStatus != FT_OK){
AddReport(String().sprintf(_T("ReadPipe()::FT_GetOverlappedResult. (0x%X)"), ftStatus));
CloseHandle(overlappedRead.hEvent);
break;
}else{ //ftStatus == FT_OK
result = 0;
break;
}
}
}
//----------------------------------------
if(FT_ReleaseOverlapped(ftHandle, &overlappedRead) != FT_OK){
AddReport("Error, ReadPipeAsync()::FT_ReleaseOverlapped");
result = -1;
}
}else{
AddReport("Error, ReadPipeAsync()::FT_InitializeOverlapped");
}
CloseHandle(overlappedRead.hEvent);
FPGAの送信ステートマシンは下記のようにしました。clkは200MHzです。(FIFOからの読込等が含まれています)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity H_FT600_S245_TX_V6 is
port
(
clk : in std_logic;
reset : in std_logic;
act : in std_logic;
fifo_data : in std_logic_vector(15 downto 0);
fifo_rdreq : out std_logic;
fifo_empty : in std_logic;
be : inout std_logic_vector(1 downto 0);
txe : in std_logic;
wr : out std_logic;
data : inout std_logic_vector(15 downto 0);
dbg_data : out std_logic_vector(15 downto 0)
);
end entity;
architecture rtl of H_FT600_S245_TX_V6 is
-- Build an enumerated type for the state machine
type state_type is (idle,s0,s1,s2,t0,t1,e0);
signal state : state_type;
signal fifo_rdreq_w : std_logic;
signal txe_r : std_logic;
signal wr_r : std_logic;
begin
fifo_rdreq <= fifo_rdreq_w and not txe;
process (clk, reset, txe, fifo_data)
begin
if reset = '1' then
state <= idle;
be <= (others=>'Z');
data <= (others=>'Z');
dbg_data <= X"0000";
wr <= '1';
wr_r <= '1';
fifo_rdreq_w <= '0';
elsif (rising_edge(clk)) then
txe_r <= txe;
wr <= wr_r;
case state is
when idle =>
wr_r <= '1';
data <= (others=>'Z');
be <= (others=>'Z');
fifo_rdreq_w <= '0';
if txe_r = '0' and act = '1' then
state <= s0;
else
state <= idle;
end if;
---------------------------------------------
when s0 =>
state <= s1;
when s1 =>
fifo_rdreq_w <= '1';
state <= s2;
when s2 =>
wr_r <= '0';
state <= t0;
--------------------------------------
when t0 =>
if txe_r = '0' then
fifo_rdreq_w <= '1';
wr_r <= '0';
data <= fifo_data;
be <= "11";
dbg_data <= fifo_data;
state <= t1;
else
fifo_rdreq_w <= '0';
wr_r <= '1';
data <= (others=>'Z');
be <= (others=>'Z');
dbg_data <= X"EEEE";
state <= e0;
end if;
when t1 =>
state <= t0;
----------------------------
when e0 =>
state <= idle;
end case;
------------------------------------------
end if;
end process;
end rtl;
受信レートの観測結果をグラフ化したものが下記になります。約180MBに近づいています。

4096Byteを受信するとしばらく待たされます。(TXEが上がる)これは受信バッファのサイズに等しいです。
SignalTapでの観測波形

クリックで全体を表示
下記もご参照ください
- FT600関連製品特設ページ:https://www.hdl.co.jp/FT600/index.html
お問い合わせについて
開発ツールの使い方などは、弊社のサポート外とさせていただいております。
ご担当の代理店様などにお尋ねください。
ソースなどの提供は行っておりません。予めご了承ください。
[kw] TEC-FPGA 2016-04-22 FT600 EDA-009 EDX-009 USB-106
[]





