1 Star 1 Fork 4

WangXuan95 / FPGA-ftdi245fifo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
GPL-3.0

语言 仿真 部署 部署

English | 中文

 

FTDI 245fifo controller

An FPGA-based controller for FT232H , FT2232H , FT600 , FT601 chips in sync-245-fifo mode, which can realize fast USB communication between FPGA and Host-PC.

Update on June 2023: Add support for byte enable signals. Now it supports all features of FTDI sync-245-fifo mode, and the length of the sending and receiving bytes no longer needs to be a multiple of FTDI chip's byte-width.

 

Introduction

sync-245-fifo mode is the highest speed transmission mode of FTDI's USB series chips. This repository implement a sync-245-fifo mode controller Verilog IP core (ftdi_245fifo_top), providing AXI-stream send and receive interfaces for Verilog developers.

In addition, this repository provides supplementary:

  • Simulation code to verify ftdi_245fifo_top
  • FPGA sample code as a demo of using ftdi_245fifo_top

For Host-PC, I provide:

  • FTDI driver installation tutorials,
  • Python3 FTDI USB software library (ftd2xx and ftd3xx) installation tutorials,
  • Several Python3 programs for testing.

Note: Although the example code of Host-PC is written in Python (I used to use Python), you can also write program in other languages (C++, C #, etc.) to communicate with the FTDI chip. The design on FPGA is not limited to which programming language you use on Host-PC.

 

module_structure
Figure1 : diagram of ftdi_245fifo_top.v

 

IP's Technical Features

  • Pure Verilog design, which is easy to transplant to FPGAs of Altera, Xilinx, or other manufacturers.
  • Standard AXI-stream interface for sending and receiving.
  • Send/Receive scheduling: The interface between FTDI USB chip and FPGA is half-duplex. This module schedules the sending and receiving using time-division multiplexing to achieve independent sending and receiving.
  • Clock Domain Crossing: The FTDI USB chip has its own clock. This module uses asynchronous FIFO to realize clock domain crossing, so that the send and receive AXI-stream interface can use custom clocks .
  • Bit width conversion: This module realizes the bit width conversion so that the bit width of the AXI-stream can be customized .

 

Performance Test Results

FT232H / FT2232H FT600 FT601
USB generation USB2.0 HS USB3.0 SS USB3.0 SS
Theoretical Throughput 60MB/s 200MB/s 400MBps
Tested Throughput (FPGA→PC) 42MB/s 140MB/s not test yet
Tested Throughput (PC→FPGA) 35MB/s 175MB/s not test yet

 

 

ftdi_245fifo Module Manual

The top design code is in ftdi_245fifo_top.v in RTL/ftdi_245fifo folder, which can be called by FPGA developers to develop their own USB communication applications. Its interface and parameters are shown in Figure2.

module_ports
Figure2 : interfaces of ftdi_245fifo.v

 

Module Parameters

To use this module, you should first determine the value of each Verilog parameter, as shown in the following table:

parameter Introduction
TX_EW Determines the data width of the AXI-stream sending interface (that is, the width of tx_data): 0 corresponds to 8bit width, 1 corresponds to 16bit width, 2 corresponds to 32bit width, and so on. It can be set arbitrarily according to your requirement and is not limited by the FTDI USB chip you used.
TX_EA Determines the depth of send buffer, depth=2^TX_EA. The default is 10 (that is, the default depth is 1024). If the FPGA BRAM is larger, it can be set larger to improve burst performance.
RX_EW Determines the data width of the AXI-stream receiving interface (that is, the width of rx_data): 0 corresponds to 8bit width, 1 corresponds to 16bit width, 2 corresponds to 32bit width, and so on. It can be set arbitrarily according to your requirement and is not limited by the FTDI USB chip you used.
RX_EA Determines the depth of receive buffer, depth=2^RX_EA. The default is 10 (that is, the default depth is 1024). If the FPGA BRAM is larger, this item can be set larger to improve burst performance.
CHIP_TYPE should be "FTx232H" , "FT600" , or "FT601" according to the FTDI chip you used

 

Module Interface: reset

The reset signal of ftdi_245fifo_top.v is:

input  wire                    rstn_async;

rstn_async is the global asynchronous reset of the module, 0 means reset, 1 means release reset. This signal can be directly set to 1'b1, or connected to the global reset signal.

 

Module Interface: Connect to FTDI Chip

The FTDI chip's signals of ftdi_245fifo_top.v are:

// Connect to FTDI chip ------------------------------
input  wire                    ftdi_clk;
input  wire                    ftdi_rxf_n;
input  wire                    ftdi_txe_n;
output wire                    ftdi_oe_n;
output wire                    ftdi_rd_n;
output wire                    ftdi_wr_n;
inout       [(8<<CHIP_EW)-1:0] ftdi_data;
inout       [(1<<CHIP_EW)-1:0] ftdi_be;

Note:

  • When the FTDI USB chip works in sync-245-fifo mode, see the chip's datasheet for its pin definations:
  • ftdi_be is the byte enable signal, only FT600 and FT601 chips have this signal. For FT232H and FT2232H, ignore it.
  • The waveform of these pins is maintained by the module. You don't need to pay attention about it. If you are interested, you can run [RTL simulation](#Module Simulation).

 

Module Interface: AXI-stream sending interface

The sending interface is a standard AXI-stream slave, which allows users to send data to FTDI chip (which will be sent to Host-PC). Corresponding definations:

// AXI-stream slave sending interface ------------------------------
input  wire                    tx_clk;       // AXI-stream's clock
output wire                    tx_tready;
input  wire                    tx_tvalid;
input  wire   [(8<<TX_EW)-1:0] tx_tdata;
input  wire   [(1<<TX_EW)-1:0] tx_tkeep;
input  wire                    tx_tlast;

Firstly, you should provide a clock on tx_clk (no special limitations of frequency, usually the main clock of FPGA). The AXI-stream is synchronized with the clock.

The operation sequence of AXI-stream is detailed in AXI-stream specification . Here is a brief explanation:

  • When tx_tready=1, the module is ready to accept a data. When tx_tready=0, the send buffer is temporarily full and no more data can be accepted.

  • When tx_tvalid=1, it means that the user wants to send a data to the send buffer. Meanwhile, tx_tdata , tx_tkeep and tx_tlast should produce a valid data.

  • tx_tvalid and tx_tready are a pair of handshake signals. When both are 1, tx_tdata is successfully sended.

  • As mentioned earlier, the parameter TX_EW determines the data bit width of the AXI-stream:

    • if TX_EW=0 , then tx_tdata is 1-byte wide (8-bits), tx_tkeep is 1-bit wide;
    • if TX_EW=1 , then tx_tdata is 2-byte wide (16-bits), tx_tkeep is 2-bit wide;
    • if TX_EW=2 , then tx_tdata is 4-byte wide (32-bits), tx_tkeep is 4-bit wide;
    • if TX_EW=3 , then tx_tdata is 8-byte wide (64-bits), tx_tkeep is 8-bit wide.
  • tx_tdata is in LITTLE ENDIAN. When Host-PC receiving data, The low byte on tx_tdata is earlier, the high byte on tx_tdata is later.

  • tx_tkeep is byte valid signal, which specifies which bytes in tx_tdata are valid (need to send) and which bytes are invalid (needn't to send)

  • For example, when tx_tdata is 4-byte wide, tx_tkeep is 4-bit wide:

    • tx_tkeep[0]=1 means tx_tdata[7:0] need to be sent. Otherwise it will not be sent
    • tx_tkeep[1]=1 means tx_tdata[15:8] need to be sent. Otherwise it will not be sent
    • tx_tkeep[2]=1 means tx_tdata[23:16] need to be sent. Otherwise it will not be sent
    • tx_tkeep[3]=1 means tx_tdata[31:24] need to be sent. Otherwise it will not be sent
  • The bits of tx_tkeep can be specified arbitrarily. For example, this strange value tx_tkeep=4'b1010 is also supported.

  • tx_tlast is the packet end signal of AXI-stream. It is used here to determine whether the current data should be sent immediately or wait for enough bit width to be saved before sending. For example, when the width of tx_tdata is 4 bytes, if the user only wants to send 1 byte (such as setting tx_tkeep=4'b0001). At this point, if tx_tlast=0 , the byte will be temporarily stored in the module and will be sent after the subsequent data arrives to make up for 4 bytes. If user wants to send it immediately, they should set tx_tlast=1 when sending tx_tdata

  • If users don't want to make it so complicated, they can set tx_tkeep to all 1 and set tx_tlast to 1. In this case, although only data with a multiple length of (2^TX_EW) can be sent, it is simpler to use.

:warning: FTDI chips can only send and receive pure data streams without the concept of data packets, so tx_tlast is only used to control whether to send immediately. After the data is sent to the computer, the software cannot know where is the boundary that tx_tlast specified.

 

Module Interface: AXI-stream receiving interface

The receiving interface is a standard AXI-stream master, which allows users to receive data from FTDI chip (from Host-PC). Corresponding definations:

// AXI-stream master receiving interface ------------------------------
input  wire                    rx_clk;       // AXI-stream clock
input  wire                    rx_tready;
output wire                    rx_tvalid;
output wire   [(8<<RX_EW)-1:0] rx_tdata;
output wire   [(1<<RX_EW)-1:0] rx_tkeep;
output wire                    rx_tlast;

Firstly, you should provide a clock on rx_clk (no special limitations of frequency, usually the main clock of FPGA). The AXI-stream is synchronized with the clock.

rx_clk can be as same as or different from tx_clk .

Note the following:

  • When rx_tready=1, it means that the user is ready to fetch out a data.
  • When rx_tvalid=1, it means that the module wants to send a data to the user. Meanwhile, a valid data appeared on rx_tdata ,rx_tkeep and rx_tlast . When rx_tvalid=0, the receive buffer is empty and no more data can be fetched out.
  • rx_tvalid and rx_tready are a pair of handshake signals. When both are 1, rx_tdata is successfully fetched out from the receive buffer.
  • As mentioned earlier, the parameter RX_EW determines the data bit width of the AXI-stream:
    • if RX_EW=0 , then rx_tdata is 1-byte wide (8-bits), rx_tkeep is 1-bit wide;
    • if RX_EW=1 , then rx_tdata is 2-byte wide (16-bits), rx_tkeep is 2-bit wide;
    • if RX_EW=2 , then rx_tdata is 4-byte wide (32-bits), rx_tkeep is 4-bit wide;
    • if RX_EW=3 , then rx_tdata is 8-byte wide (64-bits), rx_tkeep is 8-bit wide.
  • rx_tdata is in LITTLE ENDIAN. When Host-PC sending data, The earlier byte is on the low byte of rx_tdata , the later byte is on the high byte of rx_tdata .
  • rx_tkeep is the byte valid signal of AXI-stream, usually all 1. Only when Host-PC sends data with non integer multiple length of (2^RX_EW) bytes can it be not all 1.
  • rx_tlast is AXI-stream packet last signal. rx_tlast=1 indicates that there is no more data in the FTDI chip (all the data sent by the computer has been taken), and the current data is currently the last data.
  • When rx_tlast=1 , rx_tkeep may not be all 1. When rx_tlast=0 , rx_tkeep must be all 1.
  • For example, when rx_tdata is 4-byte wide, when meeting tx_tlast=1 , then rx_tkeep may be:
    • rx_tkeep=4'b0001 indicate that only rx_tdata[7:0] (1byte) is valid.
    • rx_tkeep=4'b0011 indicate that only rx_tdata[15:0] (2bytes) is valid.
    • rx_tkeep=4'b0111 indicate that only rx_tdata[23:0] (3bytes) is valid.
    • rx_tkeep=4'b1111 indicate that all rx_tdata[31:0] (4bytes) is valid.
  • rx_tkeep can only be above-mentioned patterns, and wil not be strange like rx_tkeep=4'b1010 . In contrast, the tx_tkeep signal of the sending interface mentioned above supports these strange values.

:warning: FTDI chips can only send and receive pure data streams without the concept of data packets, so rx_tlast is only used to indicate whether the current data is the last data taken out of the FTDI chip's buffer. The software on the Host-PC cannot control rx_tlast signal. For example, if you call usb.send() function twice in the software, the two blocks of data may be merged after being sent to the FPGA, and there may not be a rx_tlast=1 boundary between them.

 

Further explanation for tvalid&tready handshake

Take the following waveform as an example, in this waveform, the user interface sends 3 data: D1, D2, D3.

  • In the 1st and 2nd cycles, the user sets tx_tvalid=0 , so it is temporarily idle and no data is sent.

  • In the 3rd cycle, the user wants to send D1, so it set tx_tvalid=1, this cycle tx_tready=1, indicating that D1 is sent to buffer successfully.

  • In the 4th, 5th, 6th, and 7th cycles, the user wants to send D2, so it set tx_tvalid=1 , but the 4th, 5th, 6th cycles tx_ready=0 cause the transmission to temporarily fail until the 7th cycle tx_tready=1 is sent successfully.

  • In the 8th and 9th cycles, the user sets tx_tvalid=0, so it is temporarily idle and no data is sent.

  • In the 10th cycle, the user wants to send D3, so it set tx_tvalid=1, this cycle tx_tready=1, indicating that D3 is sent successfully.

cycle                          1     2     3     4     5     6     7     8     9     10    11
                             _    __    __    __    __    __    __    __    __    __    __    __
 clk                          \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \
                                         _____________________________             _____
tx_tvalid                    ___________/                             \___________/     \________
                             _________________                   ________________________________
tx_tready                                     \_________________/
                                         _____ _______________________             _____
tx_tdata/tx_tkeep/tx_tlast   XXXXXXXXXXXX__D1_X___________D2__________XXXXXXXXXXXXX__D3_XXXXXXXXX

 

 

Simulation

Simulation related files are in the SIM folder, where:

  • tb_ftdi_chip_model.v simulates a simple behavior of FTDI chip.
  • tb_ftdi_245fifo.v is the top module for simulation, which connect tb_ftdi_chip_model.v to ftdi_ft245fifo_top (design under test).
  • tb_ftdi_245fifo_run_iverilog.bat is the command script to run the iverilog simulation (for Windows).

The behavior of this simulation is that the FTDI chip continuously sends increasing bytes to the FPGA. The FPGA connects the AXI-stream sending interface and receiving interface loopback. Therefore, the data will be sent back to the FTDI chip, and the FTDI chip will receive the increasing bytes.

Use iverilog to simulate

Before using iverilog for simulation, you need to install iverilog , see: iverilog_usage

Then double-click tb_ftdi_245fifo_run_iverilog.bat to run simulation (only for Windows), and then you can open the generated dump.vcd file to view the waveform.

Use other simulators

You need to add all .v files in SIM folder and RTL/ftdi_245fifo folder into the simulation project. And set tb_ftdi_245fifo.v as the top. And then run simulation.

 

 

Getting started with FT232H

FT232H is a USB2.0 High Speed communication chip with a theoretical rate of 60MBps. In this demo, the FPGA communicates with Host-PC through FT232H.

:warning: This demo also applies to FT2232H (you need to work around it yourself), because FT2232H is highly similar to FT232H. Note that FT2232H's channel-A can be configured to sync-245-fifo mode , but channel-B cannot.

Step1: Install FTD2XX Driver and Library

Please follow the instructions in FTD2XX_guide.md to install the FTD2XX driver and Python FTD2XX library on your Host-PC (Windows system).

Step2: Deploy FPGA Project

Following is the hierarchical structure of the FPGA project:

Please add above-mentioned files to FPGA project

Then, please make pin constraints in the FPGA project. Specifically, you need to check the schematic of your FPGA board (or the supporting materials of the development board) to understand which FT232H pin should connected to which FPGA pin; then, constraint the signals of the top layer of the FPGA project to the corresponding FPGA pin. The correspondence is shown in the following table (this table is simplified from FT232H DataSheet page 9):

FT232H pin FT232H pin name FT232H pin name (in 245-fifo mode) signal name in top module
13 ADBUS0 D0 ftdi_data[0]
14 ADBUS1 D1 ftdi_data[1]
15 ADBUS2 D2 ftdi_data[2]
16 ADBUS3 D3 ftdi_data[3]
17 ADBUS4 D4 ftdi_data[4]
18 ADBUS5 D5 ftdi_data[5]
19 ADBUS6 D6 ftdi_data[6]
20 ADBUS7 D7 ftdi_data[7]
21 ACBUS0 RXF# ftdi_rxf_n
25 ACBUS1 TXE# ftdi_txe_n
26 ACBUS2 RD# ftdi_rd_n
27 ACBUS3 WR# ftdi_wr_n
28 ACBUS4 SIWU# ftdi_siwu (=1) :warning:
29 ACBUS5 CLKOUT ftdi_clk
30 ACBUS6 OE# ftdi_oe_n
31 ACBUS7 PWRSAV# ftdi_pwrsav (=1) :warning:
34 RESET# RESET# ftdi_resetn (=1) :warning:

:warning: SIWU#, PWRSAV# and RESET# in the above table are actually always pulled to high. Some boards directly use resistors to pull-up them without connecting them to the FPGA, in this case, you don't need to constrain these pins and simply comment out the statements related to them in fpga_top_example_ft232h.v.

 

If you want to design the FT232H PCB by yourself, please refer to Figure3.

ft232h_example_sch
Figure3 : Example schematic of FT232H USB interface circuit.

 

Notations of the clock and timing constraints:

  • There are two clocks in this project: the main clock (clk) and the clock from the FT232H chip (ftdi_clk).

  • For FT232H, ftdi_clk frequency is 60MHz.

  • There's no special limitations on the frequency of clk. which can be from a few MHz to a few hundred MHz. The simplest way is to directly use the oscillator of FPGA board.

  • constraint_ft232h.sdc shows an example of timing constraints, which constrain:

    • Frequency of ftdi_clk (60MHz)
    • Frequency of clk (you need to constrain it to the actual frequency)
    • Specify that ftdi_clk and clk are asynchronous.
  • constraint_ft232h.sdc is directly applicable to Altera Quartus projects. For Xilinx's xdc, the constraint statements should be similar (there may be some slight differences, please modify them yourself)

  • If you are lazy to make timing constraints, you can also leave them unconstrained, it is probably no problem.

 

Other Notations:

  • LED[3:0] connects 4 LEDs (not necessary) , where:
    • if ftdi_clk runs, LED[3] will blink. Usually ftdi_clk will start to run when first time of communication rather than when power on.
    • LED[2:0] shows the low 3 bits of the last-received data.
  • parameter CHIP_TYPE of ftdi_245fifo_top is set to "FTx232H", because we are using FT232H / FT2232H chip.

 

Step3: Program FT232H chip

For each FT232H chip, it needs to be programmed to 245-fifo mode when it is used for the first time. Each FT232H chip only needs to be programmed once, because there is an EEPROM chip on the periphery of the FT232H to permanently save the configuration, and it does not need to be programmed again every time it is used (unless you program it to another mode).

First go to the FTDI download page to download and install FT_Prog software. Then do the following steps:

  • Plug the USB of FT232H to the computer, and unplug all other FTDI USB chip or device (including FPGA downloaders, because some FPGA downloaders, such as Xilinx Digilent downloaders, are implemented using FT2232H chip, if the program inside the downloader is overwritten, your downloader will be broken).
  • Open FT_Prog software.
  • As shown in Figure4, click Scan and Parse (the small magnifying glass) to scan all FTDI chips plugged into the computer and find the corresponding chip of FT232H.
  • In the property tree below FT232H, expand level by level, find and click "Hardware" .
  • Select 245 FIFO mode on the right.
  • Click Program (the small lightning) in the upper toolbar.
  • A confirmation window pops up, click Program. Program to FT232H.
  • After programming, you need to re-plug the USB to let this configuration takes effect.
ft232h_program
Figure4 : Program FT232H chip to 245-fifo mode.

 

Step4: Run Programs on Host-PC

Before running these programs, make sure that FT232H has been programmed into 245-fifo mode according to step3, and the FPGA project created in step2 has been programed to FPGA.

I provide the following Python programs in python folder that will communicate with FPGA through FT232H.

File Name Function
USB_FTX232H_FT60X.py Defines the USB_FTX232H_FT60X_sync245mode class, implements constructor, close, send, recv methods. This class is universal for FT232H, FT2232H, FT600, and FT601.
usb_loopback_simple.py The Host-PC firstly sends 16 bytes to FPGA and then receives data. Because the FPGA project loopbacks data, the Host-PC will receive these 16 bytes. This program is associated with the FPGA top design fpga_top_ft232h_loopback.v
usb_loopback_mass.py The Host-PC firstly sends a large amount of data to FPGA, and then receives data. Because the FPGA project loopbacks data, the Host-PC will receive these bytes and the program will compare whether the received data is consistent with the previously sent data to verify the correctness of the loopback. This program is associated with the FPGA top design fpga_top_ft232h_loopback.v

 

 

Getting Started with FT600

The FT600 is a USB3.0 Super Speed communication chip with a theoretical rate of 200MBps. In this example, the FPGA communicates with the Host-PC through FT600.

Step1: Install FTD3XX Driver and Library

Please follow the instructions in FTD3XX_guide.md to install the FTD3XX driver and Python FTD3XX library on your Host-PC (Windows system).

Step2: Deploy FPGA Project

Following is the hierarchical structure of the FPGA project:

Please add above-mentioned files to FPGA project.

Then, please make pin constraints in the FPGA project. Specifically, you need to check the schematic of your FPGA board (or the supporting materials of the development board) to understand which FT600 pin should connected to which FPGA pin; then, constraint the signals of the top layer of the FPGA project (that is, fpga_top_example_ft600.v) to the corresponding FPGA pin. The correspondence is shown in the following table (this table is simplified from FT600 DataSheet page 7-10):

FT600 pin number FT600 pin name signal name in top module
33 DATA_0 ftdi_data[0]
34 DATA_1 ftdi_data[1]
35 DATA_2 ftdi_data[2]
36 DATA_3 ftdi_data[3]
39 DATA_4 ftdi_data[4]
40 DATA_5 ftdi_data[5]
41 DATA_6 ftdi_data[6]
42 DATA_7 ftdi_data[7]
45 DATA_8 ftdi_data[8]
46 DATA_9 ftdi_data[9]
47 DATA_10 ftdi_data[10]
48 DATA_11 ftdi_data[11]
53 DATA_12 ftdi_data[12]
54 DATA_13 ftdi_data[13]
55 DATA_14 ftdi_data[14]
56 DATA_15 ftdi_data[15]
2 BE_0 ftdi_be[0]
3 BE_1 ftdi_be[1]
43 CLKOUT ftdi_clk
5 RXF_N ftdi_rxf
4 TXE_N ftdi_txe
9 OE_N ftdi_oe
8 RD_N ftdi_rd
7 WR_N ftdi_wr
6 SIWU_N ftdi_siwu (=1) :warning:
10 RESET_N ftdi_resetn (=1) :warning:
11 WAKEUP_N ftdi_wakeupn (=0) :triangular_flag_on_post:
12 GPIO0 ftdi_gpio0 (=0) :triangular_flag_on_post:
13 GPIO1 ftdi_gpio1 (=0) :triangular_flag_on_post:

:warning: SIWU_N and RESET_N in the above table are actually always pulled to high. Some boards directly use resistors to pull-up them without connecting them to the FPGA, in this case, you don't need to constrain these pins and simply comment out the statements related to them in fpga_top_example_ft600.v.

:triangular_flag_on_post: WAKEUP_N, GPIO0 and GPIO1 in the above table are actually always pulled to GND. Some boards directly use resistors to pull-down them without connecting them to the FPGA, in this case, you don't need to constrain these pins and simply comment out the statements related to them in fpga_top_example_ft600.v.

If you want to draw FT600 PCB by yourself, please refer to Figure5.

ft600_example_sch
Figure3 : Example schematic of FT600 USB interface circuit.

 

Notations of the clock and timing constraints:

  • There are two clocks in this project: the main clock (clk) and the clock from the FT600 chip (ftdi_clk).

  • For FT600, ftdi_clk frequency is 100MHz.

  • There's no special limitations on the frequency of clk. which can be from a few MHz to a few hundred MHz. The simplest way is to directly use the oscillator of FPGA board.

  • constraint_ft600.sdc shows an example of timing constraints, which constrain:

    • Frequency of ftdi_clk (100MHz)
    • Frequency of clk (you need to constrain it to the actual frequency)
    • Specify that ftdi_clk and clk are asynchronous.
  • constraint_ft600.sdc is directly applicable to Altera Quartus projects. For Xilinx's xdc, the constraint statements should be similar (there may be some slight differences, please modify them yourself)

  • If you are lazy to make timing constraints, you can also leave them unconstrained, it is probably no problem.

 

Other Notations:

  • LED[3:0] connects 4 LEDs (not necessary) , where:
    • if ftdi_clk runs, LED[3] will blink. Usually ftdi_clk will start to run when first time of communication rather than when power on.
    • LED[2:0] shows the low 3 bits of the last-received data.
  • parameter CHIP_TYPE of ftdi_245fifo_top is set to "FT600", because we are using FT600 chip.

 

Step3: Run Programs on Host-PC

Before running these programs, make sure that the FPGA project created in step2 has been programed to FPGA.

I provide the following Python programs in python folder that will communicate with FPGA through FT600.

File Name Function
USB_FTX232H_FT60X.py Defines the USB_FTX232H_FT60X_sync245mode class, implements constructor, close, send, recv methods. This class is universal for FT232H, FT2232H, FT600, and FT601.
usb_loopback_simple.py The Host-PC firstly sends 16 bytes to FPGA and then receives data. Because the FPGA project loopbacks data, the Host-PC will receive these 16 bytes. This program is associated with the FPGA top design fpga_top_ft600_loopback.v
usb_loopback_mass.py The Host-PC firstly sends a large amount of data to FPGA, and then receives data. Because the FPGA project loopbacks data, the Host-PC will receive these bytes and the program will compare whether the received data is consistent with the previously sent data to verify the correctness of the loopback. This program is associated with the FPGA top design fpga_top_ft600_loopback.v

 

Reference

 

 

 

 

FTDI 245fifo controller

FT232HFT2232HFT600FT601 等芯片在 sync-245-fifo 模式下的控制器,实现 FPGA 与上位机 (电脑) 的高速通信。

2023/6 更新内容:加入 byte enable 信号的支持。现在已支持 FTDI sync-245-fifo 模式的所有功能,收发字节长度不再必须是 FTDI 芯片位宽的倍数。

 

简介

sync-245-fifo 模式 是 FTDI 公司的 USB 系列芯片的最高速的传输模式。本库将 sync-245-fifo 控制器封装成 Verilog 模块 (IP顶层模块名为 ftdi_245fifo_top ),它具有标准 AXI-stream 收发接口 ,供 Verilog 开发者调用。

除了 IP 核本身,本库还提供配套的:

  • 仿真代码 (Verilog)
  • IP 核调用示例 (Verilog),实现了一些简单的通信业务逻辑:回环、发送指定长度数据包等。供开发者直接上板测试。

对于电脑 (上位机) ,我提供了:

  • 驱动安装教程
  • Python3 FTDI USB 软件库 (ftd2xx 和 ftd3xx) 的安装教程
  • 几个 Python3 程序用于进行 USB 通信测试

注:虽然上位机的示例代码是用 Python 编写的 (我习惯用 Python) ,但你也可以用其它语言 (C++, C# 等) 编写上位机程序与 FTDI 芯片通信。FPGA 上的设计并不局限你在上位机上使用哪种编程语言

 

图1是该系统工作时的结构框图。

module_structure
图1:系统框图

 

特点

  • 纯 Verilog 编写,方便仿真,支持 Altera, Xilinx 等各厂商的 FPGA 。
  • 标准 AXI-stream 接口:用户通过两路 AXI-stream 收发数据 (一路发,一路收)。
  • 收发调度:FTDI USB 芯片与 FPGA 之间的接口是半双工的,该模块调度收发分时复用,在用户看来,收发的 AXI-stream 是独立的。
  • 跨时钟域:FTDI USB 芯片有自己的时钟 (ftdi_clk),该时钟并不一直运行,不能作为 FPGA 的主时钟。该模块实现了时钟域转换。
  • 位宽变换:本模块实现了位宽变换。使得 AXI-stream 接口的 位宽可自定义

 

性能测试结果

芯片型号 FT232H / FT2232H FT600 FT601
USB模式 USB2.0 HS USB3.0 SS USB3.0 SS
理论速率 60MB/s 200MB/s 400MB/s
实测速率 (FPGA→上位机) 42MB/s 140MB/s 未测
实测速率 (上位机→FPGA) 35MB/s 175MB/s 未测

 

 

ftdi_245fifo_top 模块说明

Verilog 设计代码见 RTL/ftdi_245fifo 目录中的 ftdi_245fifo_top.v ,它是IP的顶层,可供 FPGA 开发者调用来开发自己的 USB 通信业务。它的接口和参数如图2

module_ports
图2:ftdi_245fifo_top.v 的接口

 

模块参数

要调用本模块,首先要根据实际情况指定各个参数 (parameter) 的值,如下表:

parameter 说明
TX_EW 决定了用户发送接口的数据宽度 (即 tx_tdata 的宽度) : 0对应8bit宽,1对应16bit宽,2对应32bit宽,3对应64bit宽,…… 可以根据需要任意设置,不受 USB 芯片型号限制。
TX_EA 决定了用户发送缓存的深度,深度=2^TX_EA。默认为10 (深度为1024) ,如果 FPGA BRAM 较大,该项可以设得更大,来提高突发性能。
RX_EW 决定了用户接收接口的数据宽度 (即 rx_tdata 的宽度) : 0对应8bit宽,1对应16bit宽,2对应32bit宽,3对应64bit宽,…… 可以根据需要任意设置,不受 USB 芯片型号限制。
RX_EA 决定了用户接收缓存的深度,深度=2^RX_AEXP。默认为10(即默认深度为1024),如果 FPGA BRAM 较大,该项可以设得更大,来提高突发性能。
CHIP_TYPE 必须是 "FTx232H" , "FT600" , 或 "FT601"

 

模块接口:复位

复位信号见 ftdi_245fifo_top.v 代码中的:

input  wire                    rstn_async;

rstn_async 是模块的全局异步复位信号,1'b0 代表复位,1'b1 代表释放复位。在使用中,该信号可以直接设为 1'b1 ,或者连接到工程的复位信号上。

 

模块接口:连接 FTDI 芯片

FTDI 芯片信号见 ftdi_245fifo_top.v 代码中的:

// 连接 FTDI 芯片的信号 ------------------------------
input  wire                    ftdi_clk;
input  wire                    ftdi_rxf_n;
input  wire                    ftdi_txe_n;
output wire                    ftdi_oe_n;
output wire                    ftdi_rd_n;
output wire                    ftdi_wr_n;
inout       [(8<<CHIP_EW)-1:0] ftdi_data;
inout       [(1<<CHIP_EW)-1:0] ftdi_be;

这些信号应连接到 FTDI 芯片的引脚上。

  • FTDI 芯片工作在 sync-245-fifo 模式时,引脚名称见芯片 Datasheet

  • ftdi_be 是 byte enable 信号。FT232H / FT2232H 没有这个信号,此时请忽略它。

  • 这些引脚的时序由模块维护,不需要你关注。如果你感兴趣,可以运行模块仿真

 

模块接口:AXI-stream slave 发送接口

发送接口是标准 AXI-stream slave ,用户通过它发送数据给 FTDI 芯片 (最终会发送给电脑) 。对应代码中的:

// AXI-stream slave 发送接口 ------------------------------
input  wire                    tx_clk;       // AXI-stream 时钟
output wire                    tx_tready;
input  wire                    tx_tvalid;
input  wire   [(8<<TX_EW)-1:0] tx_tdata;
input  wire   [(1<<TX_EW)-1:0] tx_tkeep;
input  wire                    tx_tlast;

首先,需要提供一个 tx_clk 时钟 (频率不限,一般都提供 FPGA 主时钟) 。该 AXI-stream 同步于该时钟。

AXI-stream 的操作时序详见 《AXI-stream specification》 。这里简要说明如下:

  • tx_tready=1 时,说明模块已经准备好接收发送数据。tx_ready=0 时,发送缓存暂时满,不能接收更多数据。
  • tx_tvalid=1 时,说明用户想发送一个数据到模块内部的发送缓存。同时,tx_tdata 应产生有效数据。
  • tx_tvalidtx_tready 是一对握手信号。二者同时为 1 时, tx_tdata 成功发送。
  • 上文已经提到,参数 TX_EW 决定了该 AXI-stream 的数据位宽:
    • TX_EW=0 时,tx_tdata 宽度为 1 字节 (8-bit) ,tx_tkeep 宽度为 1-bit ;
    • TX_EW=1 时,tx_tdata 宽度为 2 字节 (16-bit) ,tx_tkeep 宽度为 2-bit ;
    • TX_EW=2 时,tx_tdata 宽度为 4 字节 (32-bit) ,tx_tkeep 宽度为 4-bit ;
    • TX_EW=3 时,tx_tdata 宽度为 8 字节 (64-bit) ,tx_tkeep 宽度为 8-bit 。
  • tx_tdata 是小端序。也即电脑收到字节流时, tx_tdata 的低位字节靠前,高位字节靠后。
  • tx_tkeep 是 AXI-stream 的有效信号,用来指定 tx_tdata 的哪些字节有效 (需要发送) ,哪些字节无效 (不需要发送) 。
  • 例如,当 tx_tdata 的位宽为 4 字节时,tx_tkeep 为 4-bit 宽:
    • tx_tkeep[0]=1 说明 tx_tdata[7:0] 需要发送,否则忽略不发送。
    • tx_tkeep[1]=1 说明 tx_tdata[15:8] 需要发送,否则忽略不发送。
    • tx_tkeep[2]=1 说明 tx_tdata[23:16] 需要发送,否则忽略不发送。
    • tx_tkeep[3]=1 说明 tx_tdata[31:24] 需要发送,否则忽略不发送。
  • tx_tkeep 的各个 bit 可以任意指定,例如 tx_tkeep=4'b1010 这种奇怪的取值也是支持的。
  • tx_tlast 是 AXI-stream 的包结尾信号。在这里用来决定当前数据是立刻发送,还是等待攒够了位宽再发送。例如,当 tx_tdata 的位宽为 4 字节时,如果用户每次只想发送 1 字节 (例如令 tx_tkeep=4'b0001 )。此时如果 tx_tlast=0 ,则该字节会暂时存在模块里,等待后续数据到来凑够 4 字节后再发送,而不会立刻发送。如果用户需要立刻发送,应该在数据有效时让 tx_tlast=1
  • 如果用户不想搞的这么复杂,可以让 tx_tkeep=全1 , tx_last=1 ,此时每次只能发送 tx_tdata 位宽个字节,每次发送的数据都立刻发送,例如若 tx_tdata 的位宽为 4 字节,则无法实现 4 的非整数倍字节的数据发送,但用起来也更简单。

:warning: FTDI 芯片只能收发单纯的数据流,而没有数据包的概念,因此 tx_tlast 仅仅用于控制是否立即发送。数据发到电脑上后,上位机的软件无法知道哪里是 tx_last 指定的包的分界点。

 

模块接口:AXI-stream master 接收接口

接收接口是标准 AXI-stream master ,用户通过它接收来自 FTDI 芯片 (来自电脑) 的数据。对应代码中的:

// AXI-stream master 接收接口 ------------------------------
input  wire                    rx_clk;       // AXI-stream 时钟
input  wire                    rx_tready;
output wire                    rx_tvalid;
output wire   [(8<<RX_EW)-1:0] rx_tdata;
output wire   [(1<<RX_EW)-1:0] rx_tkeep;
output wire                    rx_tlast;

首先,需要提供一个 rx_clk 时钟 (频率不限,一般都提供 FPGA 主时钟) 。该 AXI-stream 同步于该时钟。

rx_clk 可以和 tx_clk 是同一个时钟或不同时钟。

对 AXI-stream 各信号简要说明如下:

  • rx_tready=1 时,说明用户已经准备好拿出一个数据。
  • rx_tvalid=1 时,说明模块想发送一个数据给用户。同时,rx_tdata 上出现有效数据。而 rx_tvalid=0 时,接收缓存空,拿不出更多数据。
  • rx_tvalidrx_tready 是一对握手信号。二者同时为 1 时, rx_tdata 才成功从接收缓存中取出。
  • 上文已经提到,参数 RX_EW 决定了该 AXI-stream 的数据位宽:
    • RX_EW=0 时,rx_tdata 宽度为 1 字节 (8-bit) ,rx_tkeep 宽度为 1-bit ;
    • RX_EW=1 时,rx_tdata 宽度为 2 字节 (16-bit) ,rx_tkeep 宽度为 2-bit ;
    • RX_EW=2 时,rx_tdata 宽度为 4 字节 (32-bit) ,rx_tkeep 宽度为 4-bit ;
    • RX_EW=3 时,rx_tdata 宽度为 8 字节 (64-bit) ,rx_tkeep 宽度为 8-bit 。
  • rx_tdata 是小端序。也即 rx_tdata 的低位字节靠前,高位字节靠后。
  • rx_tkeep 是 AXI-stream 的字节有效信号,一般都是全1。只有当电脑发送了非整数位宽的数据时,才可能是非全1 。
  • rx_tlast 是 AXI-stream 的包结尾信号。在这里, tlast=1 说明 FTDI 芯片里已经没有更多的数据了 (电脑发送的所有数据已经暂时被拿完了) ,当前数据暂时是最后一拍数据了。
  • rx_tlast=1 时,rx_tkeep 可能不是全1 。当 rx_tlast=0 时,rx_tkeep 一定是全1。
  • 例如当 rx_tdata 的位宽为 4 字节时,若遇到 rx_tlast=1 ,则 rx_tkeep 可能有以下取值:
    • rx_tkeep=4'b0001 意为只有 rx_tdata[7:0] 这1字节有效;
    • rx_tkeep=4'b0011 意为只有 rx_tdata[15:0] 这2字节有效;
    • rx_tkeep=4'b0111 意为只有 rx_tdata[23:0] 这3字节有效;
    • rx_tkeep=4'b1111 (全1) 意为 rx_tdata[31:0] 这4字节都有效。
  • rx_tkeep 只可能是如上这种低位为1,高位为0的取值,不会出现 4'b1010 这种奇怪取值,也不可能是全0 。相比之下,上文的发送接口的 tx_tkeep 信号则可以很自由的取值。

:warning: FTDI 芯片只能收发单纯的数据流,而没有数据包的概念,因此 rx_tlast 仅仅用于指示当前数据是不是 FTDI 芯片缓存里拿出的最后一个数据。上位机的软件上无法控制 rx_tlast 信号。例如,如果你在软件中调用 usb.send() 函数两次,发送了两次数据,发到 FPGA 上后这两次数据可能连在一起,中间不一定有 rx_tlast=1 分界。

 

关于 AXI-stream tvalid&tready 的进一步说明

treadytvalid 的握手举例如下波形图,用户接口发送了3个数据:D1, D2, D3 。其中:

  • 第 1, 2 周期,用户令 tx_tvalid=0 ,因此暂时空闲没发数据。

  • 第 3 周期,用户要发 D1,因此令 tx_tvalid=1,本周期 tx_tready=1 ,说明 D1 即刻发送成功。

  • 第 4, 5, 6, 7 周期,用户要发 D2,因此令 tx_tvalid=1,但第 4, 5, 6 周期 tx_tready=0 导致发送暂时失败,直到第 7 周期 tx_tready=1 时,才发送成功。

  • 第 8, 9 周期,用户令 tx_tvalid=0 ,因此暂时空闲没发数据。

  • 第 10 周期,用户要发 D3,因此令 tx_tvalid=1,本周期 tx_tready=1 ,D3 即刻发送成功。

cycle                          1     2     3     4     5     6     7     8     9     10    11
                             _    __    __    __    __    __    __    __    __    __    __    __
 clk                          \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \
                                         _____________________________             _____
tx_tvalid                    ___________/                             \___________/     \________
                             _________________                   ________________________________
tx_tready                                     \_________________/
                                         _____ _______________________             _____
tx_tdata/tx_tkeep/tx_tlast   XXXXXXXXXXXX__D1_X___________D2__________XXXXXXXXXXXXX__D3_XXXXXXXXX

 

 

模块仿真

仿真相关的文件在 SIM 目录中,其中:

  • tb_ftdi_chip_model.v 模拟了一个简单的 FTDI 芯片的行为。
  • tb_ftdi_245fifo.v 是 testbench 的顶层,它把 tb_ftdi_chip_model.v 和待测模块 (也即 ftdi_245fifo_top.v ) 连起来进行仿真。
  • tb_ftdi_245fifo_run_iverilog.bat 是运行 iverilog 仿真的命令脚本 (仅对Windows)。

该仿真的行为是:FTDI 芯片不断发送不断递增的字节给 FPGA ,FPGA 将 AXI-stream 发送接口和接收接口回环 (loopback) 连接,因此数据会被发回 FTDI 芯片,因此 FTDI 芯片会收到不断递增的字节。

使用 iverilog 仿真

使用 iverilog 进行仿真前,需要安装 iverilog ,见:iverilog_usage

然后双击 tb_ftdi_245fifo_run_iverilog.bat 运行仿真,然后可以打开生成的 dump.vcd 文件查看波形。

使用其它仿真工具

需要把 SIM 目录和 RTL/ftdi_245fifo 目录中 的所有 .v 文件加入仿真工程,以 tb_ftdi_245fifo.v 为仿真的顶层模块,然后运行仿真。

 

 

开始使用 FT232H

FT232H 是 USB2.0 High Speed 通信芯片,本例实现 FPGA 通过 FT232H 与上位机进行通信。

:warning: 本例也适用于 FT2232H (具体操作时需要你自己变通变通),因为 FT2232H 与 FT232H 高度相似。注意 FT2232H 的 channel-A 可配置成 sync-245-fifo 模式 ,而 channel-B 则不行。

步骤1:安装驱动和库

请按照 FTD2XX_guide.md 的指示在上位机 (以Windows系统为例) 上安装 FTD2XX 驱动和 Python FTD2XX 库。

步骤2:部署 FPGA 工程

以下是该 FPGA 工程的模块层次结构:

请将以上 .v 文件加入工程。

然后,请在 FPGA 工程中进行引脚约束,具体而言,你需要查看电路板的原理图 (或开发板配套资料) ,了解 FT232H 的各引脚被连接到了 FPGA 的哪些引脚号上;然后,把 FPGA 工程的顶层的信号分配到对应的 FPGA 引脚号上,使得这些信号与 FT232H 的引脚对应起来。对应关系见下表 (该表简化自 FT232H DataSheet 第9页) :

FT232H引脚号 FT232H引脚名 FT232H引脚名 (245-fifo 模式下) 应约束到顶层的信号名
13 ADBUS0 D0 ftdi_data[0]
14 ADBUS1 D1 ftdi_data[1]
15 ADBUS2 D2 ftdi_data[2]
16 ADBUS3 D3 ftdi_data[3]
17 ADBUS4 D4 ftdi_data[4]
18 ADBUS5 D5 ftdi_data[5]
19 ADBUS6 D6 ftdi_data[6]
20 ADBUS7 D7 ftdi_data[7]
21 ACBUS0 RXF# ftdi_rxf_n
25 ACBUS1 TXE# ftdi_txe_n
26 ACBUS2 RD# ftdi_rd_n
27 ACBUS3 WR# ftdi_wr_n
28 ACBUS4 SIWU# ftdi_siwu (=1) :warning:
29 ACBUS5 CLKOUT ftdi_clk
30 ACBUS6 OE# ftdi_oe_n
31 ACBUS7 PWRSAV# ftdi_pwrsav (=1) :warning:
34 RESET# RESET# ftdi_resetn (=1) :warning:

:warning: SIWU# 、 PWRSAV# 和 RESET# 实际上是要永远被拉为高电平的 (你也可以看到在 fpga_top_example_ft232h.v 中它们被 assign 为 1) ,因此有些板子的设计直接用电阻把它们拉到高电平上,而没有连接到 FPGA ,对于这种情况,就不用在 FPGA 约束它们的引脚,并直接在 fpga_top_example_ft232h.v 中注释掉与它们相关的语句即可。

 

如果你要自己画 FT232H 的 PCB,可参考图3

ft232h_example_sch
图3:FT232H USB 接口电路的参考原理图设计

 

关于本工程的时钟和时序约束:

  • FPGA 工程存在两个时钟:主时钟 (clk) 和 FT232H 芯片提供的时钟 (ftdi_clk) 。
  • 对于 FT232H , ftdi_clk 频率为 60MHz 。
  • clk 的频率比较自由,几 MHz 到几百 MHz 都可以。最简单的就是直接用开发板的晶振。
  • constraint_ft232h.sdc 展示了时序约束示例,它约束了:
    • ftdi_clk 的频率 (60MHz)
    • clk 的频率 (你需要根据实际频率去约束)
    • 指定 ftdi_clk 和 clk 为异步关系
  • constraint_ft232h.sdc 直接适用于 Altera Quartus 工程,对于 Xilinx 的 xdc ,约束语句应该差不多 (可能有点小区别,请自行修改)
  • 如果懒得进行时序约束,也可以不约束,大概率不会有问题。

 

在 FPGA 工程中,另外注意以下几点:

  • LED[3:0] 信号连接了4颗 LED 灯 (不是必须的) ,其中:
    • 如果 ftdi_clk 启动,LED[3] 会闪烁,否则不闪烁。一般 ftdi_clk 只会在第一次通信时启动,而不是上电就启动。
    • LED[2:0] 展示上次收到的数据的最低 3 bit。
  • ftdi_245fifo_top 模块的参数 CHIP_TYPE 被设为 "FTx232H" ,这是因为我们用的是 FT232H / FT2232H 芯片。

然后你就可以编译工程,步骤略。

 

步骤3:烧录 FT232H 芯片

针对每颗 FT232H 芯片,需要在初次使用时烧录为 sync-245-fifo 模式。每颗 FT232H 芯片只需要烧录一次,因为 FT232H 外围会有个 EEPROM 芯片用来永久保存配置,之后每次使用都不需要再烧录 (除非你又烧录了其它模式) 。

首先进入 FTDI官网下载页面 下载并安装 FT_Prog 软件。然后进行以下步骤:

  • 在电脑上插入你需要烧录的 FT232H 的 USB 接口,并拔出所有其它 FTDI USB 设备 (包括拔出所有的 FPGA 下载器,因为很多 FPGA 下载器,例如 Xilinx Digilent 下载器是 FT2232H 芯片实现的,如果万一覆盖了下载器内部的程序,你的下载器就废了) 。
  • 打开 FT_Prog 软件。
  • 图4,点击 Scan and Parse (小放大镜) ,扫描出插在该电脑的所有 FTDI 芯片,找到 FT232H 对应的芯片。
  • 在 FT232H 下方的属性树中逐级展开,找到并点击 Hardware 。
  • 在右侧选择 245 FIFO 模式。
  • 点击上方工具栏中的 Program (小闪电) 。
  • 弹出确认窗口,点击 Program。烧录到 FT232H 。
  • 烧录后,需要重新拔插 FT232H 的 USB 接口,该配置才能生效。
ft232h_program
图4:烧录 FT232H 芯片,配置为 245-fifo 模式。

 

步骤4:在电脑上运行通信程序

运行这些程序之前,请确保 FT232H 已经按照步骤3被烧录为 sync-245-fifo 模式,且 FPGA 中下载了步骤2中建立的工程。

我在 python 文件夹中提供了以下几个 Python 程序,它们会通过 FT232H 与 FPGA 进行通信。

文件名 功能
USB_FTX232H_FT60X.py 定义了 USB_FTX232H_FT60X_sync245mode 类,用来对 FTDI USB 设备进行打开、关闭、发送数据、接收数据。适用于 FT232H、FT2232H、FT600、FT601 。会被以下程序调用。
usb_loopback_simple.py 上位机先发送 16 字节给 FPGA ,然后接收数据。因为 FPGA 工程将收发回环连接,所以上位机会接收到这 16 字节。该程序和 FPGA 顶层设计 fpga_top_ft232h_loopback.v 配套。
usb_loopback_mass.py 上位机先发送发送大量数据给 FPGA ,然后接收数据。因为 FPGA 工程将收发回环连接,所以上位机会接收到这些字节,程序会判断收到的数据和之前发出去的数据是否一致,来验证回环的正确性。该程序和 FPGA 顶层设计 fpga_top_ft232h_loopback.v 配套。

 

 

开始使用 FT600

FT600 是 USB3.0 Super Speed 通信芯片,本例实现 FPGA 通过 FT600 与上位机进行通信。

步骤1:安装驱动和库

请按照 FTD3XX_guide.md 的指示在 Host-PC (Windows系统) 上安装 FTD3XX 驱动和 Python FTD3XX 库。

步骤2:部署 FPGA 工程

以下是该 FPGA 工程的模块层次结构:

请将以上 .v 文件加入工程。

然后,请在 FPGA 工程中进行引脚约束,具体而言,你需要查看电路板的原理图 (或开发板配套资料),了解 FT600 的各引脚被连接到了 FPGA 的哪些引脚号上;然后,把 FPGA 工程的顶层的信号分配到对应的 FPGA 引脚号上,使得这些信号与 FT600 的引脚对应起来。对应关系见下表 (该表简化自 FT600 DataSheet 第 7~10 页) :

FT600引脚号 FT600引脚名 应约束到顶层的信号名
33 DATA_0 ftdi_data[0]
34 DATA_1 ftdi_data[1]
35 DATA_2 ftdi_data[2]
36 DATA_3 ftdi_data[3]
39 DATA_4 ftdi_data[4]
40 DATA_5 ftdi_data[5]
41 DATA_6 ftdi_data[6]
42 DATA_7 ftdi_data[7]
45 DATA_8 ftdi_data[8]
46 DATA_9 ftdi_data[9]
47 DATA_10 ftdi_data[10]
48 DATA_11 ftdi_data[11]
53 DATA_12 ftdi_data[12]
54 DATA_13 ftdi_data[13]
55 DATA_14 ftdi_data[14]
56 DATA_15 ftdi_data[15]
2 BE_0 ftdi_be[0]
3 BE_1 ftdi_be[1]
43 CLKOUT ftdi_clk
5 RXF_N ftdi_rxf
4 TXE_N ftdi_txe
9 OE_N ftdi_oe
8 RD_N ftdi_rd
7 WR_N ftdi_wr
6 SIWU_N ftdi_siwu (=1) :warning:
10 RESET_N ftdi_resetn (=1) :warning:
11 WAKEUP_N ftdi_wakeupn (=0) :triangular_flag_on_post:
12 GPIO0 ftdi_gpio0 (=0) :triangular_flag_on_post:
13 GPIO1 ftdi_gpio1 (=0) :triangular_flag_on_post:

:warning: SIWU_N 和 RESET_N 实际上是要永远被拉为高电平的,因此有些板子的设计直接用电阻把它们拉到高电平上,而没有连接到 FPGA ,对于这种情况,就不用在 FPGA 约束它们的引脚,并直接在 fpga_top_example_ft600.v 中注释掉与它们相关的语句即可。

:triangular_flag_on_post: WAKEUP_N 、 GPIO0 和 GPIO1 实际上是要永远被拉为低电平的,因此有些板子的设计直接用电阻把它们拉到GND上,而没有连接到 FPGA ,对于这种情况,就不用在 FPGA 约束它们的引脚,并直接在 fpga_top_example_ft600.v 中注释掉与它们相关的语句即可。

 

如果你要自己画 FT600 的 PCB,可参考图5

ft600_example_sch
图5:FT600 USB 接口电路的参考原理图设计

 

关于本工程的时钟和时序约束:

  • FPGA 工程存在两个时钟:主时钟 (clk) 和 FT600 芯片提供的时钟 (ftdi_clk) 。
  • 对于 FT600 / FT601 , ftdi_clk 频率为 100MHz 。
  • clk 的频率比较自由,几 MHz 到几百 MHz 都可以。最简单的就是直接用开发板的晶振。
  • constraint_ft600.sdc 展示了时序约束示例,它约束了:
    • ftdi_clk 的频率 (100MHz)
    • clk 的频率 (你需要根据实际频率去约束)
    • 指定 ftdi_clk 和 clk 为异步关系
  • constraint_ft600.sdc 直接适用于 Altera Quartus 工程,对于 Xilinx 的 xdc ,约束语句应该差不多 (可能有点小区别,请自行修改)
  • 如果懒得进行时序约束,也可以不约束,大概率不会有问题。

 

在 FPGA 工程中,另外注意以下几点:

  • LED[3:0] 信号连接了4颗 LED 灯 (不是必须的) ,其中:
    • 如果 ftdi_clk 启动,LED[3] 会闪烁,否则不闪烁。一般 ftdi_clk 只会在第一次通信时启动,而不是上电就启动。
    • LED[2:0] 展示上次收到的数据的最低 3 bit。
  • ftdi_245fifo_top 模块的参数 CHIP_TYPE 被设为 "FT600" ,这是因为我们用的是 FT600 芯片。

然后你就可以编译工程,步骤略。

 

步骤3:在电脑上运行通信程序

运行这些程序之前,请确保 FPGA 中下载了步骤2中建立的工程。

我在 python 文件夹中提供了以下几个 Python 程序,它们会通过 FT600 与 FPGA 进行通信。

文件名 功能
USB_FTX232H_FT60X.py 定义了 USB_FTX232H_FT60X_sync245mode 类,用来对 FTDI USB 设备进行打开、关闭、发送数据、接收数据。适用于 FT232H、FT2232H、FT600、FT601 。会被以下程序调用。
usb_loopback_simple.py 上位机先发送 16 字节给 FPGA ,然后接收数据。因为 FPGA 工程将收发回环连接,所以上位机会接收到这 16 字节。该程序和 FPGA 顶层设计 fpga_top_ft600_loopback.v 配套。
usb_loopback_mass.py 上位机先发送发送大量数据给 FPGA ,然后接收数据。因为 FPGA 工程将收发回环连接,所以上位机会接收到这些字节,程序会判断收到的数据和之前发出去的数据是否一致,来验证回环的正确性。该程序和 FPGA 顶层设计 fpga_top_ft600_loopback.v 配套。

 

参考资料

GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: <program> Copyright (C) <year> <name of author> This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>. The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <https://www.gnu.org/licenses/why-not-lgpl.html>.

简介

FPGA-based USB fast data transmission using FT232H/FT600 chip. 使用FT232H/FT600芯片进行FPGA与电脑之间的高速数据传输。 展开 收起
Verilog 等 3 种语言
GPL-3.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Verilog
1
https://gitee.com/wangxuan95/FPGA-ftdi245fifo.git
git@gitee.com:wangxuan95/FPGA-ftdi245fifo.git
wangxuan95
FPGA-ftdi245fifo
FPGA-ftdi245fifo
main

搜索帮助