FTDI社のUSB3.0ブリッジIC FT600の動作速度をEDX-009で測定しました

 FTDI社のUSB3.0ブリッジIC FT600の転送レートをEDX-009を用いて実際に計測しました。
EDX-009はXILINX社のKintex-7とFT600をクレジットカードサイズのボードに搭載したFPGAボードです。

 転送レートの理論値はデータ16bit幅・100MHz動作という仕様から、200MB/s (MByte/sec 以下同様)となっています。
アプリケーションで計測を行った結果、下記のようになりました。

  • 送信:約190MB/s
  • 受信:約175MB/s

以下計測の詳細です。

 

設定

以下の設定で測定を行いました。

  • FT600動作モード:245 FIFO, 100MHz
  • 測定範囲(送信):100kB(102400 Byte)~20,000kB を100kB Step (200点)
  • 測定範囲(受信):100kB(102400 Byte)~10,000kB を100kB Step (100点)
  • 測定回数:10回を平均
  • D3XXデバイスドライババージョン:v1.1.0.0
  • 実験ボード:EDX-009

 

送信レート観測

 PCアプリケーションからFPGAへデータを送信し、ステータスが送信完了となるまでの時間を測定します。
観測結果は下図のようになりました。転送量が増えるにつれて190MB/sに近づいています。

 6000 Byteを送信したときの観測波形をいくつか示します。サンプリングクロックは200MHzです。
ある一定数(512/1024/2048 Bytes)送信した際にRXFが上がり転送が一時中断するようです。中断時間は数clock~500clockなどまちまちでした。

FPGA受信波形1

クリックして拡大

FPGA受信波形2

クリックして拡大

FPGA受信波形3

クリックして拡大

 

受信レート観測

 PCから受信を要求し、FPGAからPCへデータを送信、ステータスが送信完了となるまでの時間を測定します。
観測結果は下図のようになりました。約175MBに近づいています。

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

FPGA送信波形

クリックして拡大

 

送信 - PCアプリプログラム例
	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;

 

受信 - PCアプリプログラム例 
	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;

 

 

下記もご参照ください

 

お問い合わせについて

開発ツールの使い方などは、弊社のサポート外とさせていただいております。
ご担当の代理店様などにお尋ねください。

ソースなどの提供は行っておりません。予めご了承ください。

 


[kw] 2016-11-08 FT600 EDA-009 EDX-009 USB-106


[]