Introduction:
The FTDI FT2232H USB 2.0 chip available 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 Channel A is available for custom usage. This article demonstrates communication between host and the board using Synchronous FIFO mode via channel A of FT2232H. The Channel A of FT2232H, when configured as FIFO, acts as a USB-FIFO bridge between host and FPGA. Synchronisation is done using the 60 MHz clock available on FT2232H (All the FIFO signals are triggered in synchronisation with 60 MHZ clock available on FT2232H). Let’s get started!
Prerequisites:
- Hardware:
- Telesto MAX 10 FPGA Module
- Intel USB Blaster II (optional)
- USB A to Micro B Cable
- Software
- Quartus software 17.0 or newer
- Python 2.7
Step 1:
Open Quartus -> File -> New, select New Quartus Prime Project and click OK.
Step 2:
A Project Wizard will open up, click Next. In ‘Directory, Name and Top-Level Entity’, select appropriate directory and give proper project name.
Step 3:
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) and click Next, then again Next and finally Finish.
Step 4:
In ‘Project Navigator’, Select ‘Files’ to view all files, then Right-Click ‘Files’ and select ‘Add/Remove files from project’.
Step 5:
Download and extract the RTL source files from here and add them in the project by browsing to proper directory.
Here, FTDI’s Synchronous FIFO interface is used to perform data transfer between FPGA and host PC. As the mode of data transfer is synchronous, the data transfers occur in synchronisation with clock available on FTDI. The speed is much higher than that of asynchronous FIFO. To use the synchronous 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 rd_n
.
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 written on data
bus is driven into FIFO.
oe_n
: it is an active low output enable input signal. When asserted, data
is driven on ‘data’ bus, then rd_n is enable after 1 clock period.
In the RTL code, FSM is implemented, it checks whether there is some data in FIFO for reading (indicated by pending_read
), if so, oe_n
is asserted, followed by assertion of rd_n
, data is read. After this, oe_n
and rd_n
signals are de-asserted. If there is data to be written (indicated by pending_write
), wr_n
is enabled and data is written into FPGA.
Step 6:
Click on ‘Analysis & Synthesis’ from task menu.
Step 7:
Go to Assignments -> Pin Planner.
Step 8:
Copy the following pin configurations in your pin planner and close the pin planner.
Step 9:
Compile the project by selecting ‘Start Compilation’ from Processing menu. Program the module by clicking Program Device.
Step 10:
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.
Step 11:
To check if Synchronous 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 ‘sync_fifo_test.py’. Download and install the ‘ftd2xx’ Python library.
from __future__ import print_function import time import random import ftd2xx BLOCK_LEN = 1024 * 100 def init(): dev = ftd2xx.openEx('Telesto MAX10 FPGA Module A',2) time.sleep(0.1) dev.setTimeouts(5000, 5000) time.sleep(0.1) dev.setBitMode(0xff, 0x00) time.sleep(0.1) dev.setBitMode(0xff, 0x40) time.sleep(0.1) dev.setUSBParameters(0x10000, 0x10000) time.sleep(0.1) dev.setLatencyTimer(2) time.sleep(0.1) dev.setFlowControl(ftd2xx.defines.FLOW_RTS_CTS, 0, 0) time.sleep(0.1) dev.purge(ftd2xx.defines.PURGE_RX) time.sleep(0.1) dev.purge(ftd2xx.defines.PURGE_TX) time.sleep(0.1) return dev tx_data = str(bytearray([ random.randrange(0, 256) for i in range(BLOCK_LEN)])) #ftd2xx.open() dev = init() print("\nDevice Details :") print("Serial : " , dev.getDeviceInfo()['serial']) print("Type : " , dev.getDeviceInfo()['type']) print("ID : " , dev.getDeviceInfo()['id']) print("Description : " , dev.getDeviceInfo()['description']) print("\nWriting %d KB of data to the deivce..." % (BLOCK_LEN / 1024)) ts = time.time() written = dev.write(tx_data) print("\nReading %d KB of data from the deivce..." % (BLOCK_LEN / 1024)) rx_data = dev.read(BLOCK_LEN) te = time.time() 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("\nSynchronous Test Finished Successfully!\nThank You!!")
Open command prompt. Change to the directory of the file sync_fifo_test.py
and enter the following command:
python sync_fifo_test.py