Styx Xilinx Zynq FPGA Module

FTDI Synchronous FIFO interfacing with Styx

48 views August 9, 2024 gayathri-ks 1

Introduction:

The FTDI FT2232H USB 2.0 chip available on-board Styx 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 Styx, channel B is used for FPGA configuration and flash programming whereas Channel A is available for custom usage. This article demonstrates communication between the 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. Synchronization is done using the 60 MHz clock available on FT2232H. Let’s get started!

Styx Z7 FPGA Module

Styx Z7 FPGA Module is the first product from Numato Lab featuring Zynq-70xx SoC. Styx is pin-compatible with Numato Lab’s Saturn Spartan 6 FPGA moduleNeso Artix 7 FPGA module and Skoll Kintex 7 FPGA module and allows for seamless upgrade in most cases. Styx offers built in USB 2.0 interface that can be used to program the board as well as do debugging or data transfer with the host.

Styx Z7 FPGA Module  features a Zynq 7020 from Xilinx in CLG484 package. The unique feature of Zynq-7000 series is that they are complete System on Chip (SoC) with an FPGA die which makes it a very powerful combination. Zynq 7020 has dual-core ARM Cortex A9 and a whole bunch of peripherals which are typically found in SoCs. Additionally, it has Artix-7 equivalent programmable logic section, connected to SoC using AXI interconnects. This SoC + FPGA combination makes Zynq very flexible for multitude of uses. With Zynq 7020 on board, Styx is a great choice for learning, product development and OEM integration.

Prerequisites

To follow this article, you would need the following:

  • Hardware:
    1. Styx Z7 FPGA Module
    2. Xilinx Platform Cable II JTAG debugger.
  • Software:
    1.  Vivado Design Suite 2024.1
    2. FT_Prog tool for configuring on-board FT2232H USB Serial converter (download and install from FTDI website)
    3. python 3.12

Let’s get started

The following steps will walk you through the process of creating a new project with Vivado . This article is written for Numato Lab’s Styx Zynq Module, but can be adapted to any other Zynq based platform with minor changes. Screenshots are added wherever possible to make the process easier to the reader.

Step 1:

Download and install Vivado Board Support Package files for Styx from here. Follow the readme in the link on how to install Vivado Board Support Package files for Numato Lab’s boards.

Step 2:

Start Vivado Design Suite, and select “Create New Project” from Quick Start section. The project wizard will pop up.  Press next to proceed with creating the project.

Step 3:

Type in a project name and save it at a convenient location. For this example “Styx_sync_fifo” is used as project name, but feel free to use any name. Select the check box below to keep all project files in a single folder. The image below shows the settings for the example project. Click “Next” to continue.

Step 4:

Choose “RTL Project” as project type and check the option “Do not specify sources at this time”

Step 5:

At the “Default Part” step, select “Boards” and choose Vendor as “numato.com”. Select “Styx” and click “Next”. If Styx is not displayed in the boards list, you will need to install Styx board support files correctly.

Continue the wizard and finish creating the project. When the new project wizard exits, a new project will be opened up in Vivado with the settings you have selected.

Step 6:

Right-Click  on ‘Design Sources’ and select ‘Add Sources’. It will open a configuration window for adding Verilog files.

Step 7:

Download and extract the RTL Code files from here. Now Click ‘Add Files’, select all files and add them to the project.

Here, FTDI’s Synchronous FIFO interface is used to perform data transfer between FPGA and host PC. As the operation is Synchronous, the data transfers occur in synchronization with clock. 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 a 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 ondata 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 an 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 8:

Right-Click on Constraints and select ‘Add sources’.

 

Step 9:

Click Next and then ‘Create File’. Enter a name for the constraints file and Click Finish.

Step 10:

Copy the following constraints to the newly created .xdc file.

set_property -dict { PACKAGE_PIN  "Y6"       IOSTANDARD LVCMOS33   SLEW FAST} [get_ports {clk}]       
set_property -dict { PACKAGE_PIN  "M19"      IOSTANDARD LVCMOS33     SLEW FAST    PULLUP TRUE } [get_ports {rst}]
set_property -dict { PACKAGE_PIN  "W20"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {rxf_n}]  
set_property -dict { PACKAGE_PIN  "Y21"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {txe_n}] 
set_property -dict { PACKAGE_PIN  "W21"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {wr_n}]  
set_property -dict { PACKAGE_PIN  "L18"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {clkout}] 
set_property -dict { PACKAGE_PIN  "U20"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {oe_n}]   
set_property -dict { PACKAGE_PIN  "V20"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {siwu}]      
set_property -dict { PACKAGE_PIN  "Y20"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {rd_n}]  
set_property -dict { PACKAGE_PIN  "T22"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {data[0]}] 
set_property -dict { PACKAGE_PIN  "T21"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {data[1]}]   
set_property -dict { PACKAGE_PIN  "U22"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {data[2]}] 
set_property -dict { PACKAGE_PIN  "U21"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {data[3]}]  
set_property -dict { PACKAGE_PIN  "V22"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {data[4]}]  
set_property -dict { PACKAGE_PIN  "W22"      IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {data[5]}]   
set_property -dict { PACKAGE_PIN  "AA22"     IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {data[6]}]   
set_property -dict { PACKAGE_PIN  "AB22"     IOSTANDARD LVCMOS33     SLEW FAST} [get_ports {data[7]}]   

Step 11:

Click “Generate Bitstream” under PROGRAM AND DEBUG section and click “Yes” in any subsequent dialog window which comes up.

Step 12:

Once the bitstream is successfully generated, close any “Bitstream Generation Completed” dialog which comes up asking for what to do next.

Step 13:

Click on “Open Hardware Manager” and then select “auto connect”.

Then, Right Click on  xc7z020_1 -> Program device.

Dialog window for programming will open. Program the bit file by clicking ‘Program’.

Step 14:

Once the device is programmed, program proper FTDI Settings for FIFO to work.

Change FT Prog settings as follows: Go to Device:0 -> Hardware Specific -> Port A -> Hardware and select 245 FIFO.

Now go to Hardware Specific -> Port A -> Driver and select D2XX Direct.

Then click on program device.

Step 15:

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 ‘sync_test.py’.

 from __future__ import print_function
 import time
 import random
 import ftd2xx

 BLOCK_LEN = 2048 * 32
 def init():
 dev = ftd2xx.openEx(b'Styx Zynq 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 = bytes(bytearray([ random.randrange(0, 256) for i in range(BLOCK_LEN)]))

 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!!")


Step 16:

Open command prompt in the file directory and give the following command

python sync_fifo_test.py

Output:

 

Was this helpful?

Leave A Comment
*
*