0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

在icestick板子上實現(xiàn)從FPGA到USB Host的數(shù)據(jù)傳輸

OpenFPGA ? 來源:OpenFPGA ? 2023-03-09 14:18 ? 次閱讀

背景信息

icestick 板載 USB 接口芯片 FT2232H 的端口 A 和端口 B 均與 FPGA ice40hx1k 相連。其中,端口 A 處于 MPSSE 模式,用于讀寫 SPI Flash 以更新 FPGA 的 bitfile,而 B 口默認處于 ASYNC Serial 模式,當作串口使用。

端口 B 都只有一部分引腳連到 FPGA,無法支持 245 FIFO 或者 245 FIFO SYNC 模式以實現(xiàn)高速數(shù)據(jù)傳輸。而在 ASYNC Serial 模式時,其支持最大 12Mbaud 即最高 1.14MBps 的數(shù)據(jù)傳輸。

筆者發(fā)現(xiàn) FT2232H 還支持一種稱為 Fast Opto-Isolated Serial Interface 的模式。在 FTDI 文檔和軟件中,這一模式也被稱為 Fast Serial Interface 模式或者 OPTO Isolate 模式。因為引入了時鐘引腳,這一模式可以在使用較少引腳的情況實現(xiàn)比 ASYNC Serial 模式更高帶寬的數(shù)據(jù)傳輸。

讀者可以通過此文了解 OPTO Isolate 模式如何使用并按照說明可以實現(xiàn)最高 2.57MBps 的數(shù)據(jù)傳輸。

準備工作

你需要具備以下條件:

一塊 icestick 開發(fā)板

ice40 FPGA 開發(fā)工具,開源工具或者 iceCube2

FT Prog 程序及 D2XX 驅動

FT2232H Datasheet

同時,筆者使用以下軟件實現(xiàn) Windows 端測試程序:

zadig 軟件

libusb 庫及開發(fā)環(huán)境

準備妥當后,我們先嘗試修改 FT2232H 芯片端口 B 的模式。

修改模式

首先,我們需要使用 FTDI 公司的 FT Prog 程序來修改端口 B 的模式。而 FT Prog 程序則需要驅動程序 D2XX 驅動。

打開設備管理器,插入 icestick 后,如果 D2XX 設備驅動程序配置正常,在通用總線控制器下會出現(xiàn) USB Serial Converter AUSB Serial Converter B 設備,如下圖所示。

3b79a10c-be40-11ed-bfe3-dac502259ad0.png

打開 FT Prog 程序,主菜單上點擊 DEVICES 然后點擊 Scan and Parse 子菜單。如果一切正常,讀者應該可以看到以下界面:

3b962c96-be40-11ed-bfe3-dac502259ad0.png

選中設備,找到 Hardware SpecificPort BHardware 項,選擇 OPTO Isolate 項,然后在主菜單上點擊 DEVICES 然后點擊 Program 子菜單。

3bb04e50-be40-11ed-bfe3-dac502259ad0.png

點擊 Program 按鈕就可以將修改后的配置選項寫入 FT2232H 的 EEROM 中。

燒寫完畢后可以重新拔插 icestick,打開 FT Prog 再次查看設備的 Port B 的屬性是否已經修改成 OPTO Isolate。

修改成功后,我們看一下 OPTO Isolate 模式下接口的規(guī)格。

OPTO Isolate 模式

在 FT2232H Datasheet 章節(jié) 3.1.4.6 FT2232H Pins used as a Fast Serial Interface 的 Table 3.10 中我們可以找到:

3bc1c6e4-be40-11ed-bfe3-dac502259ad0.png

由于本文側重于 FPGA 到 FT2232H 的數(shù)據(jù)傳輸,我們可以暫時忽略用于 FT2232H 到 FPGA 方向數(shù)據(jù)傳輸?shù)?FSDO 引腳。

在章節(jié) 4.8.2 Incoming Fast Serial Data 中 Figure 4.15 Fast Opto-Isolated Serial Interface Input Data 我們可以看到:

3bd7bb8e-be40-11ed-bfe3-dac502259ad0.png

有此時序圖我們可以看出:

空閑狀態(tài)下 FSCTS 和 FSDI 應為高電平

FSCLK 作為數(shù)據(jù)傳輸?shù)膮⒖紩r鐘,F(xiàn)T2232H 應在 FSCLK 的上升沿采數(shù)據(jù)

FSCTS 為高電平時,F(xiàn)PGA 可以進行數(shù)據(jù)傳輸

一次傳輸?shù)臄?shù)據(jù)由一個由 0 表示的起始位、LSB 優(yōu)先的 8 位數(shù)據(jù)和一個 DEST 位組成

在 DEST 位發(fā)送后,F(xiàn)SCTS 仍然會保持一段時間的低電平

然后我們在章節(jié) 4.8 Fast Opto-Isolated Serial Interface Mode Description 的 Figure 4.13 Fast Opto-Isolated Serial Interface Signal Waveforms 看到具體時序:

3beb1170-be40-11ed-bfe3-dac502259ad0.png

以及在同一章節(jié)的 Table 4.6 Fast Opto-Isolated Serial Interface Signal Timings 看到具體時序:

3c040310-be40-11ed-bfe3-dac502259ad0.png

根據(jù)這些,我們可以得到:

FSCLK 的最小周期是 20ns,即最大頻率是 50MHz

FSDI 的建立時間最小為 10ns,保持時間最小為 5 ns

這樣我們可以根據(jù)這些參數(shù)進行 FPGA 接口設計了。

接口電路設計

在實現(xiàn)接口電路之前,讀者需要檢查具體用到的 FPGA 的性能。如果 IO 反轉性能不能達到 50MHz,那么 IO 就成為瓶頸;如果 IO 性能滿足要求,但是接口電路頻率不能超過 100MHz 或者在支持支持雙沿輸出和輸入的情況下超過 50MHz,接口電路就會成為瓶頸。

通過查看 ice40hx1k 的文檔,我們可以大致確定 ice40hx1k 的普通 IO 反轉可以做到 50MHz,而且,在此 FPGA 上實現(xiàn)一個運行在近 100MHz 的電路并不十分困難。

如果我們使用 100MHz 作為內部時鐘,那么數(shù)據(jù)傳輸時序圖會變成:

3c1ce7ae-be40-11ed-bfe3-dac502259ad0.png

需要說明的是

我們使用 100MHz 使用來產生一個 50MHz 的 FSCLK 對應 IO 的反轉

我們在 FSCLK 的下降沿變更數(shù)據(jù),這樣保證 FSDI 的建立時間和保持時間都是 10ns

我們會產生一個持續(xù)反轉的 FSCLK,而不會在不傳輸數(shù)據(jù)的時候暫停 FSCLK

通過觀察時序圖,計數(shù)狀態(tài)機來實現(xiàn)此電路較為簡單。同時對于慢速接口電路,valid-ready 信號也是不能缺少的。加入這些信息后,數(shù)據(jù)傳輸時序圖會變成:

3c30780a-be40-11ed-bfe3-dac502259ad0.png

有了這樣的時序圖,我們可以開始實現(xiàn)具體的電路了。

接口電路實現(xiàn)

首先,輸入信號 FSCTS 需要經過跨時鐘域處理。我們可以將 i_fscts 連接到 2 個級聯(lián)的 DFF 上來進行處理,從而得到同步的信號 w_fscts。

//
//CDCsignals
//
localparamDFF_W=2;

wirew_fscts;
reg[DFF_W-1:0]r_fscts_sync;

always@(posedgei_clk)
r_fscts_sync<=?{r_fscts_sync[DFF_W?-?2?:?0],?i_fscts};

????assign?w_fscts?=?r_fscts_sync[DFF_W?-?1];

其次,F(xiàn)ast Opto-Isolated Serial Interface 電路本質是將并行的數(shù)據(jù)進行串行數(shù)據(jù),我們還需要一個移位寄存器和對應的控制信號:

//
//r_data
//
//r_datakeepsthedatatobetransmitted
//
localparamTX_DATA_W=DATA_W+3;

reg[TX_DATA_W-1:0]r_data;
reg[TX_DATA_W-1:0]w_data_next;

wirew_data_tick;
wirew_data_load;
wirew_status_tick;

always@(posedgei_clk,posedgei_arst)
if(i_arst)
r_data<=?{TX_DATA_W{1'b1}};
????????else
????????????r_data?<=?w_data_next;

????always?@(*)?begin
????????w_data_next?=?r_data;

????????if?(w_data_load)
????????????w_data_next?=?{i_channel,?i_data,?2'b01};
????????else
????????????if?(w_data_tick)
????????????????w_data_next?=?{1'b1,?r_data[TX_DATA_W?-?1?:?1]};
????end

????//?w_data_load?indicates?if?r_data?could?be?filled?safely
????assign?w_data_load?=?o_ready?&?i_valid;
????assign?w_data_tick?=?w_status_tick?|?w_status_start;

因為數(shù)據(jù)的發(fā)送需要兩個必備條件,我們需要一個 bit 來確保默認情況 FSDI 的數(shù)據(jù)為高電平。這樣,加上起始位和 DEST 位后,我們共需要 11 位移位寄存器。

同時,數(shù)據(jù)發(fā)送時 LSB 優(yōu)先的,我們的 FSDI 自然而然的會連接到移位寄存器的最低位。

復位時,移位寄存器全部填充為 1;復位解除后,如果需要加載數(shù)據(jù)時,即 w_data_load 為有效時,那么將表示 DEST 位的 i_channel、8 位數(shù)據(jù) i_data 、表示起始位的 0 和默認電平 1 加載到寄存器中;如果遇到 w_data_tick 有效時,那么就將移位寄存器進行右移,最高位填充 1。

然后,因為數(shù)據(jù)發(fā)送的兩個條件并不是同時發(fā)生,我們需要一個寄存器來表示 r_data 是否已經填充。

//
//r_data_status
//
//r_data_statusdecidesthevalid-readysignalsand
//ifr_statusFSMstarts
//
regr_data_filled;
regr_data_filled_next;

wirew_data_done;
wirew_status_done;

always@(posedgei_clk,posedgei_arst)
if(i_arst)
r_data_filled<=?1'b0;
????????else
????????????r_data_filled?<=?r_data_filled_next;

????always?@(*)?begin
????????r_data_filled_next?=?r_data_filled;

????????//?if?the?tx?data?has?been?filled
????????if?(r_data_filled)?begin
????????????//?and?the?data?transmission?has?been?done
????????????if?(w_data_done)
????????????????r_data_filled_next?=?1'b0;
????????end
????????//?or?if?the?tx?data?is?empty
????????else?begin
????????????//?and?upstream?module's?data?is?ready
????????????if?(i_valid)
????????????????r_data_filled_next?=?1'b1;
????????end
????end

????assign?w_data_done?=?w_status_done?&?i_tick;

默認的情況下,r_data_filled 為 0 表示 r_data 是沒有填充的;如果沒有填充過且輸入數(shù)據(jù)有效,那么就將 r_data_filled 設置為 1,表示已經填充;如果已經填充,且表示數(shù)據(jù)已經完全被發(fā)送出去,即 w_data_done 為 1 時將 r_data_filled 設置為 0。

接著,我們需要實現(xiàn)一個計數(shù)狀態(tài)機來控制 r_data 的移位和 r_data_filled 的更新。

//
//r_status
//
//r_statuscontrolsTXFSM
//
localparamSTATUS_MAX=11;
localparamSTATUS_W=$clog2(STATUS_MAX);

reg[STATUS_W-1:0]r_status;
reg[STATUS_W-1:0]w_status_next;

wirew_status_start;
wirew_status_idle;

assignw_status_idle=(r_status=={STATUS_W{1'b0}});
assignw_status_done=(r_status==(STATUS_MAX[STATUS_W-1:0]-1'b1));
assignw_status_tick=i_tick&~w_status_idle;

always@(posedgei_clk,posedgei_arst)
if(i_arst)
r_status<=?{STATUS_W{1'b0}};
????????else
????????????r_status?<=?w_status_next;

????always?@(*)?begin
????????w_status_next?=?r_status;

????????if?(w_status_start)
????????????w_status_next?=?{{STATUS_W-1{1'b0}},?1'b1};
????????else
????????????if?(w_status_tick)
????????????????if?(w_status_done)
????????????????????w_status_next?=?{STATUS_W{1'b0}};
????????????????else
????????????????????w_status_next?=?r_status?+?1'b1;
????end

????//?FSM?begins?counting?when?FSM?is?idle
????assign?w_status_start?=?w_status_idle?&
????????????????????????????//?r_data?is?filled
????????????????????????????r_data_filled?&
????????????????????????????//?i_fstcs?is?ready?to?receive?data
????????????????????????????w_fscts?&
????????????????????????????//?to?sync?with?o_fsclk?signal
????????????????????????????i_tick;

計數(shù)狀態(tài)機的實現(xiàn)并不復雜。默認情況下,計數(shù)器為 0 表示接口處于空閑狀態(tài);在處于空閑狀態(tài)下,如果 r_data 已經被填充,F(xiàn)SCTS 信號為高,在保證與時鐘同步的情況下,計數(shù)器變成 1,然后每個 w_status_tick 有效時加一,知道計到最大狀態(tài) 10 之后又變?yōu)?0,等待 w_status_start 再次變?yōu)?1。

最后,有了上述電路,那么輸出信號處理就較為簡單。

//
//outputsignals
//
//r_dataisreadywhenr_data_filledis0
assigno_ready=~r_data_filled;

assigno_fsdi=r_data[0];

對于 o_ready 信號,只要數(shù)據(jù)發(fā)送完畢就可以進行填充;而 FSDI 信號直接取 r_data 的最低位。

為了測試這一接口模塊,我們還需要設計另外一個控制模塊來產生數(shù)據(jù)并驅動此接口模塊。筆者實現(xiàn)了一個控制模塊,支持周期發(fā)送和最大帶寬發(fā)送兩種模式選擇。限于篇幅,此處不再贅述其實現(xiàn)細節(jié)。

控制模塊的代碼、接口模塊的代碼、cocotb 仿真代碼及 icestick 完整的工程可以在 icestick-oifs 庫中 gateware 目錄 oifs-tx 子目錄下找到。

需要注意的是,由于 icestick 板載晶振頻率 12MHz,使用 PLL 倍頻出最大符合規(guī)范的時鐘頻率為 99MHz,所以,實際的 FSCLK 的反轉頻率是 49.5MHz,而非設計時的 50MHz。

FPGA 部分實現(xiàn)完畢后,我們還需要實現(xiàn) USB Host 側的軟件來接收數(shù)據(jù)。

USB Host 側軟件

為了實現(xiàn)跨平臺的代碼,筆者使用 libusb 庫進行 USB Host 側的代碼。

在 Windows 上,讀者需要使用 zadig 軟件將端口 B 的 D2XX 驅動替換成 libusb 的驅動。如下圖所示:

3c50e9dc-be40-11ed-bfe3-dac502259ad0.png

同時,筆者在 msys2 環(huán)境下安裝 mingw-w64-x86_64-libftdi 和必要的開發(fā)工具,用來構建 USB Host 側的程序。

筆者編寫了兩個程序,一個程序用來讀取數(shù)據(jù)并計算性能,名為 oifs-rxperf,另外一個程序用來將數(shù)據(jù)打印到控制臺,名為 oifs-rxdump。

USB Host 側代碼可以在 icestick-oifs 庫中 software 目錄下找到。這些代碼可以不用修改或者稍加修改運行在 Linux 平臺上。

測試結果

筆者在 Windows 上測試的結果如下:

3c67925e-be40-11ed-bfe3-dac502259ad0.png

我們可以看到最高的傳輸速率可以達到 2.57MBps。筆者在 Ubuntu 20.04 和 Ubuntu 22.04 中分別進行了測試,測試結果與 Windows 平臺上得到的結果一致。

在接口邏輯仿真環(huán)境中,我們假設了 FSCTS 信號總高,但是實際情況并非如此:

3c895934-be40-11ed-bfe3-dac502259ad0.png

通過邏輯分析儀抓到信號的波形來看,F(xiàn)SCTS 在 DEST 位傳輸完畢后保持 140ns 的低電平,那么一次傳輸需要大概 364ns 到 384ns,則極限帶寬則約為 2.61MBps。

總結

按照本文的說明及相應的代碼,讀者應該可以在 icestick 上實現(xiàn)從 FPGA 到 USB Host最高 2.57MBps 的數(shù)據(jù)傳輸,從而將 icestick 變成一個 USB 數(shù)據(jù)采集板。







審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1625

    文章

    21620

    瀏覽量

    601231
  • usb
    usb
    +關注

    關注

    60

    文章

    7876

    瀏覽量

    263692
  • fifo
    +關注

    關注

    3

    文章

    386

    瀏覽量

    43492
  • FT2232H
    +關注

    關注

    1

    文章

    4

    瀏覽量

    9872

原文標題:如何將 FPGA 變成 USB 數(shù)據(jù)采集板

文章出處:【微信號:Open_FPGA,微信公眾號:OpenFPGA】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    基于FPGA的高速LVDS數(shù)據(jù)傳輸

    22.4Gbps(Kintex-7).2. 1對LVDS接收時鐘+16對LVDS接收數(shù)據(jù).本人可以提供FPGA源代碼.同時還可以Xilinx評估板ML555/ML605/KC705上演示驗證.如有高速LVDS
    發(fā)表于 03-01 18:47

    求助 ,關于STM32的USB數(shù)據(jù)傳輸問題

    小弟正在做一項目,利用 STM32做的關于數(shù)據(jù)采集系統(tǒng),打算利用USB實現(xiàn)和PC的數(shù)據(jù)傳輸,目前了解的資料多是關于
    發(fā)表于 07-06 22:02

    基于FPGA+USB3.0接口的高速數(shù)據(jù)傳輸系統(tǒng)設計

    優(yōu)點,通過USB3.0接口的超高速傳輸特性,可有效地解決高速數(shù)據(jù)采集中的數(shù)據(jù)傳輸和存儲問題,測量結果誤差小,可信度高,有利于實現(xiàn)
    發(fā)表于 08-09 14:18

    汽車行駛記錄儀的數(shù)據(jù)傳輸設計

    ,建議采用主結構式USB接口;2.標準RS232CD型9針接口。具備上述通信接口的基礎,本標準不排除同時使用其他通信方式的可能性。”針對以上要求,可以采用如下幾種數(shù)據(jù)傳輸的方案。采
    發(fā)表于 12-04 10:37

    如何實現(xiàn)ISO數(shù)據(jù)傳輸

    你好,我正在嘗試實現(xiàn)一個USB麥克風(用于測試ADC精度和USB特性)設備,PSoC枚舉工作良好。我無法找到任何有關如何實現(xiàn)ISO數(shù)據(jù)傳輸
    發(fā)表于 03-26 13:10

    USB數(shù)據(jù)傳輸接口電路設計

      USB數(shù)據(jù)傳輸接口電路設計  USB接口有數(shù)據(jù)傳輸速度快、連接簡單、兼容性好等特點。汽車行駛記錄儀國家標準考慮RS232接口使用的普及
    發(fā)表于 06-17 05:00

    如何實現(xiàn)FPGA和PC之間的數(shù)據(jù)傳輸

    嗨, 我正在使用Saturn Spartan6 numato板。我董事會中實現(xiàn)了一個非常簡單的要求版本?,F(xiàn)在我想將數(shù)據(jù)傳輸FPGA或從FPGA
    發(fā)表于 07-31 10:36

    如何將FPGA變成USB數(shù)據(jù)采集板呢?

    icestick 實現(xiàn)從 FPGA USB Host
    發(fā)表于 03-21 14:34

    基于USB接口的無線數(shù)據(jù)傳輸系統(tǒng)設計

    本文提出了一種運用USB接口芯片PDIUSBD12、89C52微處理器、射頻收發(fā)器nRF401構建的無線USB數(shù)據(jù)傳輸接口,并利用該接口成功地實現(xiàn)了無線
    發(fā)表于 09-24 15:48 ?91次下載

    基于FPGAUSB的高速數(shù)據(jù)傳輸、記錄及顯示系統(tǒng)

    摘要:提出了一種基于FPGAUSB的高速數(shù)據(jù)傳輸、記錄及顯示系統(tǒng)的設計方案,并對其中的低電壓差分信號(LVDS
    發(fā)表于 04-16 21:36 ?646次閱讀
    基于<b class='flag-5'>FPGA</b>和<b class='flag-5'>USB</b>的高速<b class='flag-5'>數(shù)據(jù)傳輸</b>、記錄及顯示系統(tǒng)

    基于DSP的USB數(shù)據(jù)傳輸系統(tǒng)設計

    基于DSP的USB數(shù)據(jù)傳輸系統(tǒng)設計 引 言   由于DSP芯片的不斷發(fā)展,以及它處理數(shù)據(jù)速度快、處理數(shù)據(jù)量大的優(yōu)勢,已經廣泛應用到數(shù)字信號處理的許多領域。
    發(fā)表于 11-20 10:50 ?1308次閱讀
    基于DSP的<b class='flag-5'>USB</b><b class='flag-5'>數(shù)據(jù)傳輸</b>系統(tǒng)設計

    基于USB2.0的紅外數(shù)據(jù)傳輸系統(tǒng)的設計與實現(xiàn)

    基于USB2.0的紅外數(shù)據(jù)傳輸系統(tǒng)的設計與實現(xiàn) 摘要:針對有線傳輸的缺點或不足,為避免經常插拔接口造成測試儀器損壞,設計基于USB2.0的
    發(fā)表于 03-13 09:56 ?1584次閱讀
    基于<b class='flag-5'>USB</b>2.0的紅外<b class='flag-5'>數(shù)據(jù)傳輸</b>系統(tǒng)的設計與<b class='flag-5'>實現(xiàn)</b>

    數(shù)據(jù)傳輸速率是什么意思

    數(shù)據(jù)傳輸速率是什么意思 數(shù)據(jù)傳輸速率是通過信道每秒可傳輸的數(shù)字信息量的量度。數(shù)據(jù)傳輸速率也稱為吞吐率。數(shù)據(jù)傳輸速率由很
    發(fā)表于 03-18 14:45 ?4985次閱讀

    USB2.0+FPGA實現(xiàn)多路數(shù)據(jù)傳輸系統(tǒng)

    基于USB2.0 的FIFO 方式, 利用FPGA 同步實現(xiàn)三個通道, 不同傳輸率的數(shù)據(jù)的發(fā)送和采集, 詳細說明多路
    發(fā)表于 09-13 17:22 ?66次下載
    <b class='flag-5'>USB2.0+FPGA</b><b class='flag-5'>實現(xiàn)</b>多路<b class='flag-5'>數(shù)據(jù)傳輸</b>系統(tǒng)

    基于EDMA實現(xiàn)TMS320C64X與FPGA數(shù)據(jù)傳輸

    基于EDMA實現(xiàn)TMS320C64X與FPGA數(shù)據(jù)傳輸
    發(fā)表于 10-21 10:14 ?5次下載
    基于EDMA<b class='flag-5'>實現(xiàn)</b>TMS320C64X與<b class='flag-5'>FPGA</b>的<b class='flag-5'>數(shù)據(jù)傳輸</b>