The FTDI FT2232H USB 2.0 chip on-board Telesto provides users with a FIFO interface for data transfer between FPGA and host PC. The FT2232H chip features two channels or ports, which can be configured into various modes like UART, FIFO, JTAG etc. On Telesto, channel B is used for FPGA configuration and flash programming, whereas the channel A is available for custom usage. This article demonstrates communication with Telesto using Asynchronous FIFO mode on Channel A of FT2232H. The Channel A on FT2232H, when configured as FIFO, acts as a USB-FIFO bridge between host and FPGA. This article is applicable for Telesto MAX 10 FPGA Module. Let’s get started!
- Telesto MAX 10 FPGA Module
- Intel USB Blaster II (optional)
- USB A to Micro B Cable
- Quartus software 17.0 or newer
- Python 2.7
Open Quartus -> File -> New. Select New Quartus Prime Project and click OK.
A Project Wizard will open up. Click Next. In ‘Directory, Name and Top-Level Entity’, type in a project name and select a convenient project location. Enter “ft2232h_phy_top” as top module name.
Click Next till you see the ‘Family, Device and Board Settings’ tab. In Boards select ’10M16DAF484C8G’ (select corresponding 10M50 part if your Telesto is of 10M50 variant), click Next twice and finally click Finish.
In ‘Project Navigator’, Select ‘Files’ to view all files. Right-Click ‘Files’ and select ‘Add/Remove files from project’.
Download and extract the RTL source code from here and add them to the project.
Here, FTDI’s Asynchronous FIFO interface is used to perform data transfer between FPGA and host PC. As the operation is asynchronous, the data transfers is not synchronous to any common clock between FPGA and FTDI. The design is simpler but has relatively lower speed than synchronous FIFO interface. To use the asynchronous FIFO transfer mode available on FT2232H, its hardware and driver must be configured as 245 FIFO and D2XX respectively. In this article, Channel A of FT2232H is configured as FIFO, which provides the following signals:
data: It is bi-directional bus carrying the 8-bit FIFO data.
rxf_n: It is an active low signal. When de-asserted, does not read data from FIFO. When it is enabled, it indicates that there is some data available in FIFO, the data is read after asserting
txe_n: It is an active low signal. When de-asserted, does not write data to FIFO. When it is asserted, data can be written to FIFO if
wr_n is asserted.
rd_n: It is an active low signal. When asserted,
data is driven onto ‘data’ bus from FIFO.
wr_n: It is an active low signal. When asserted,
data from ‘data’ bus is driven into FIFO.
In the RTL code, FSM is implemented which checks if there is some data available for reading (indicated by
pending_read), then the data is read by enabling
rd_n signal. When there is some data to be written (indicated by
wr_n signal is asserted and incoming data is driven into FIFO.
Save the project and click ‘Analysis & Synthesis’ from task menu.
go to Assignments -> Pin Planner.
Copy the following pin configurations in your pin planner and close the pin planner.
Compile your design. Program the module by clicking Program Device.
The Programmer window will open. Click “Start” and wait for the device to get programmed. Make sure you have connected Telesto with USB Blaster and powered up before attempting to program it. You might need to go to “Hardware Setup…” to choose your JTAG hardware. Click ‘Start’ to program.
To check if Asynchronous FIFO is working as expected, write some data through FIFO, read it back and compare it. If the data written matches the data that is read then it means that the design is working fine.
To check this, copy the following python code in text editor and save it as ‘async_test.py’. Download and install the ‘ftd2xx’ Python library.
from __future__ import print_function import time import random import ftd2xx dev = ftd2xx.openEx('Telesto MAX10 FPGA Module A', 2) dev.setTimeouts(5000, 5000) dev.purge(ftd2xx.defines.PURGE_TX|ftd2xx.defines.PURGE_RX) print("\nDevice Details :") print("Serial : " , dev.getDeviceInfo()['serial']) print("Type : " , dev.getDeviceInfo()['type']) print("ID : " , dev.getDeviceInfo()['id']) print("Description : " , dev.getDeviceInfo()['description']) BLOCK_LEN = 2048 * 10 tx_data = str(bytearray([ random.randrange(0, 256) for i in range(BLOCK_LEN) ])) print("\nWriting %d KB of data to the deivce..." % (BLOCK_LEN / 1024)) ts = time.time() written = dev.write(tx_data) rx_data = dev.read(BLOCK_LEN) te = time.time() print("\nReading %d KB of data from the deivce..." % (BLOCK_LEN / 1024)) p = te - ts print("\nComparing data...\n") if (tx_data == rx_data): print("Data written matches the data read\n") else: print("Data verification failed\n") dev.close() print("Transfer Time = %.3f seconds" % p) speed = (BLOCK_LEN / 1024./1024 / p) print("Transfer Rate = %.3f MB/s" % speed) print("\nAsynchronous Test Finished Successfully!\nThank You!!")
Open command prompt. Change to the directory of the file
async_test.py and enter the following command: