Quantcast
Channel: FPGA Developer
Viewing all 89 articles
Browse latest View live

Using the AXI DMA Engine

$
0
0

Update 2014-08-06: This tutorial is now available in a Vivado version – Using the AXI DMA in Vivado

One of the essential devices for maximizing performance in FPGA designs is the DMA Engine. DMA stands for Direct Memory Access and a DMA engine allows you to transfer data from one part of your system to another. The simplest usage of a DMA would be to transfer data from one part of the memory to another, however a DMA engine can be used to transfer data from any data producer (eg. an ADC) to a memory, or from a memory to any data consumer (eg. a DAC). In older systems, the processor would handle all data transfers between memories and devices. As the complexity and speed of systems increased over time, this method obviously was not sustainable. DMA was invented to remove the bottleneck and free up the processor from having to deal with transferring data from one place to another. In high performance digital and FPGA systems, the data throughput is typically way too high for the processor to deal with, so a DMA is essential.

Xilinx provides us with an AXI DMA Engine IP core in its EDK design tool. In this tutorial, I’ll write about how to add a DMA engine into your design and how to connect it up to a data producer/consumer. We will test the design on the ZC706 evaluation board. We’ll use the Xilinx DMA engine IP core and we’ll connect it to the processor memory. The data producer/consumer will be created using the Peripheral Wizard which will generate a custom IP core that implements an AXI streaming input (data consumer) and an AXI streaming output (data producer). Internally, the AXI streams will be connected in loopback to enable us to test the design. After, you will be able to break the loop and insert whatever devices you would like, be it an IP core for processing data, an ADC, a DAC, you name it.

 

Start with the base project

You will need to use the Base System Builder to create the base EDK project. If you are not familiar with the BSB, I have gone through this process in another tutorial here: Using the base system builder. Otherwise you can download the base project from my Github page at the link below:

https://github.com/fpgadeveloper/zc706-bsb

In this tutorial, I have copied the base project files into a folder called “zc706-axi-dma”.

 

Add the DMA Engine

Open the base EDK project using Xilinx Platform Studio 14.7. Your screen should look somewhat like the image below.axi_dma_edk_0000

 

In the IP catalog, open the “DMA and Timer” branch and find the “AXI DMA Engine” IP core.

Right click on the AXI DMA Engine and select “Add IP”.axi_dma_edk_0001

 

Click Yes to confirm.axi_dma_edk_0002

 

EDK will now open the settings for the AXI DMA Engine.axi_dma_edk_0035

 

Disable the Scatter Gather Engine and click OK. EDK will then propose to make the connections to the processor for you. Click OK.axi_dma_edk_0004

 

The EDK will then place the DMA into our base design. Click on the “Bus Interfaces” tab to see the AXI DMA Engine in our design and how it’s connected.axi_dma_edk_0005axi_dma_edk_0006

 

 

Expand the axi_dma_0 branch to see the bus connections.axi_dma_edk_0007

What just happened?

Over those few steps there was quite a bit of magic performed behind the curtains, here are a few things that the EDK has done for you:

  • An AXI interconnect was added to the design and labelled “axi_interconnect_1″. The base design had only an AXI lite interface to connect the processor to the GPIO peripherals DIP_Switches_4Bits, GPIO_SWs and LEDs_3Bits. For a high performance DMA, you need a full AXI interconnect.
  • The DMA bus ports have been connected. I’ll explain these buses in another post.
  • The DMA interrupts have been connected to the processor. You have to click on the Ports tab to see this.
  • The DMA engine has been given an address on the memory map. You have to click on the Addresses tab to see this.

Notice that there are four buses that are not connected to anything:

  • M_AXIS_MM2S
  • S_AXIS_S2MM
  • M_AXIS_MM2S_CNTRL
  • S_AXIS_S2MM_STS

The last two are control buses which we will not use. The first two buses are the AXI streaming master and slave interfaces (the data producer and data consumer respectively). We will have to connect these up to the custom peripheral that we will generate in the next few steps.

 

Create the data producer/consumer peripheral

We’ll now use the Peripheral Wizard to create an IP core that will serve as our data producer/consumer. It will have an AXI streaming master interface (output/producer) and an AXI streaming slave interface (input/consumer).

From EDK, select Hardware->Create or Import Peripheral.axi_dma_edk_0008

 

The Peripheral Wizard will open to the welcome screen. Click Next.axi_dma_edk_0009

Select “Create templates for a new peripheral” and click Next.axi_dma_edk_0010

 

The next window wants to know where you will place the peripheral files. Tick “To an XPS project”, make sure that the folder is your current project and click Next.axi_dma_edk_0011

 

Now you have to name the peripheral. I called mine “axi_stream_generator” but you can use the name you like. In a real-world design, this peripheral would be wrapping your data producer or data generator, so it might be called “axi_adc” or “axi_dac” depending on what device you are pushing data to or getting data from.axi_dma_edk_0012

 

Now you have to chose the type of AXI interface for this peripheral. We want to use AXI streaming.axi_dma_edk_0013

 

On the next page we provide information specific to the loopback example that the EDK will generate. The example peripheral will take in a number of 32-bit words on the AXI-stream slave interface (let’s call it a packet), calculate the sum of those values and then output the sum on the AXI-stream master interface. This page of the wizard allows us to specify the packet size. Leave the default of 8 x 32-bit words and click Next.axi_dma_edk_0014

 

Just click Next on the page for optional file generations. We wont need any of that.axi_dma_edk_0015

 

Click Finish on the last page and EDK will generate the template for our new custom peripheral.axi_dma_edk_0016

 

If you now go down to the bottom of your IP catalog, you should see your custom peripheral listed in the Project Local PCores->USER branch.

 

Patch time

The template that the EDK just generated for us is great, however it doesn’t quite satisfy the requirements for the AXI streaming interfaces of the DMA Engine. The AXI streaming protocol includes a signal called TLAST which should be asserted when the last data is sent, unfortunately the template peripheral generated by the Peripheral Wizard does not drive the TLAST signal and so we have to make a minor modification to the code.

In your favourite text editor, open the file “\zc706-axi-dma\EDK\pcores\axi_stream_generator_v1_00_a\hdl\vhdl\axi_stream_generator.vhd”. This is the VHDL code for the peripheral template we just generated.

Replace ALL the code with the following code you can get from Github:

https://github.com/fpgadeveloper/zc706-axi-dma/blob/master/EDK/pcores/axi_stream_generator_v1_00_a/hdl/vhdl/axi_stream_generator.vhd

Save and close the file.

If you want to eventually modify the custom peripheral to suit your application, this is the file you will have to modify so I suggest you read the code and try to get a good idea of how it works.

 

Add the Custom Peripheral to the project

Right click on the IP core we just created (“axi_stream_generator” or whatever you called it) and select “Add IP”.axi_dma_edk_0017

 

Click Yes to confirm.axi_dma_edk_0018

 

EDK will now open the configuration window for the peripheral. Just leave the defaults and click OK.axi_dma_edk_0019

 

Now go into the Bus Interfaces tab and open up the axi_stream_generator branch to display its buses.axi_dma_edk_0020

 

We must now connect the buses as follows:

  • S_AXIS of the axi_stream_generator_0 must be connected to “axi_dma_0_M_AXIS_MM2S”axi_dma_edk_0021

 

  • S_AXIS_S2MM of the axi_dma_0 must be connected to “axi_stream_generator_0_M_AXIS”axi_dma_edk_0022

 

After making those connections, your Bus Interfaces window should look like in the image below.axi_dma_edk_0023

 

Shift over the bus visualization window to see the AXI streaming buses in a light blue colour.axi_dma_edk_0024

 

Now you can see that we have an AXI streaming interface going from the DMA to our peripheral, and another going from our peripheral to the DMA.

You will not find our custom peripheral in the Addresses tab because being an AXI streaming peripheral, it is not on the memory map.

 

Patch time

Normally the Xilinx tools would connect up the clock and reset signals for our custom peripheral when we make the bus connections. In this case, it hasn’t done so, so we have to do it manually.

Using your favourite text editor, open the system.mhs file from the EDK project folder.

Go to the bottom of the file and find the following code:

BEGIN axi_stream_generator
 PARAMETER INSTANCE = axi_stream_generator_0
 PARAMETER HW_VER = 1.00.a
 BUS_INTERFACE S_AXIS = axi_dma_0_M_AXIS_MM2S
 BUS_INTERFACE M_AXIS = axi_stream_generator_0_M_AXIS
END

Add two lines to make it the following:

BEGIN axi_stream_generator
 PARAMETER INSTANCE = axi_stream_generator_0
 PARAMETER HW_VER = 1.00.a
 BUS_INTERFACE S_AXIS = axi_dma_0_M_AXIS_MM2S
 BUS_INTERFACE M_AXIS = axi_stream_generator_0_M_AXIS
 PORT ACLK = processing_system7_0_FCLK_CLK0
 PORT ARESETN = processing_system7_0_FCLK_RESET0_N_0
END

Save the file and close it.

 

Generate the bitstream

In EDK click Generate Bitstream.axi_dma_edk_0025

 

Once the bitstream has been generated, click “Export Design” to bring the design into SDK.axi_dma_edk_0025a

 

Click “Export and Launch SDK”.axi_dma_edk_0026

 

Software Development Kit

  1. The SDK should automatically open after the design is exported.
  2. When the SDK starts up, it will ask you which workspace to open. Create a folder called SDK in the zc706-axi-dma folder (or the project folder you are using) and select this as your workspace. Click OK.axi_dma_edk_0027

 

SDK opens up with a welcome screen that should look like the following image.axi_dma_edk_0028

 

Now we need to create an application that will run on our ZC706 evaluation board and test our DMA engine. We will use the UART as an output console so that we can put print statements in our code to make it easier to see what is going on.

Select “File->New->Application project”.axi_dma_edk_0028a

 

In the dialog box that appears, type the name of the project as “dma_test” and click “Next”.axi_dma_edk_0029

 

We’re now asked if we would like to use a template for the application. Select the “hello world” template and click “Finish”.axi_dma_edk_0029a

 

The SDK will now build the dma_test application and the dma_test BSP (board support package). When it is finished, your Project Explorer should look like the image below.axi_dma_edk_0031

 

Modify the application code

Now we will add code to the template to test our DMA. Double click the helloworld.c file to open it in the SDK, then replace ALL the code with the following code on Github:

https://github.com/fpgadeveloper/zc706-axi-dma/blob/master/SDK/dma_test/src/helloworld.c

When you select Save, the SDK should automatically start building the application.

The code at the link above comes from an example provided by Xilinx in the installation files. You can find it at this location on your PC:
C:\Xilinx\14.7\ISE_DS\EDK\sw\XilinxProcessorIPLib\drivers\axidma_v7_02_a\examples\xaxidma_example_simple_poll.c

By the way, if you didn’t know about it already, that folder contains heaps of examples that you will find useful, I suggest you check it out.

Once the application is built, you’re ready to run it on the ZC706 evaluation board.

 

Load the FPGA with the bitstream

1. Turn on your hardware platform (ZC706 or whatever you are using).

2. Connect a USB cable from your board’s UART port (J21 on the ZC706) to your computer’s USB port.

3. Open your terminal program (eg. Putty or Miniterm) and connect to the COM port that corresponds to your UART over USB device. Make sure the port settings are 115200 baud, 8-bits, no parity, 1 stop bit.axi_dma_edk_0033

 

4. From the SDK menu, select “Xilinx Tools->Program FPGA”.axi_dma_edk_0033a

 

5. In the “Program FPGA” dialog box, the defaults should already specify the correct bitstream for the hardware project. Make sure they correspond to the image below and click Program.axi_dma_edk_0033b

 

The Zynq will then be programmed with the bitstream and the console window should give you the message:

FPGA configured successfully with bitstream "E:/Github/fpgadeveloper/zc706-axi-dma/SDK/EDK_hw_platform/system.bit"

Run the Software Application

1. First make sure that the dma_test application is selected in the Project Explorer, then select “Run->Run” or click the icon with the green play symbol in the toolbar.axi_dma_edk_0033c

 

2. In the “Run As” dialog box, select “Launch on Hardware” and click OK.axi_dma_edk_0034

 

3. SDK will then program the Zynq with the dma_test application and run it. You should see the following output in your terminal window.axi_dma_edk_0036

 

If you go through the application code, you will see that the test is run 10 times. This is what we did in each test:

  • We write a packet of 8 words (specifically 0,1,2,3,4,5,6,7) to a transmit buffer that is located in memory
  • We setup and trigger a DMA transfer from our peripheral to the receive buffer (streaming to memory mapped) – at this point there is no data being sent by our peripheral, but we setup the RX in preparation because there soon will be.
  • We setup and trigger a DMA transfer from the transmit buffer to our peripheral (memory mapped to streaming) – this triggers the DMA to send the data from memory to the AXI-streaming master interface, which is connected to the AXI-streaming slave interface of our custom peripheral. That data then gets summed and the answer gets pumped out of the AXI-streaming master interface 8 times (the size of one packet).
  • We wait for both transfers to complete.
  • We read the receive buffer which is also located in memory and the DMA should have just filled up with the received data.
  • We print the received data to the console.

The result should be 0+1+2+3+4+5+6+7=28=0x1C in hexadecimal!

If you want the source code for this project, you can get it from my Github page at the link below:

https://github.com/fpgadeveloper/zc706-axi-dma


Creating a Base System for the Zynq in Vivado

$
0
0

Tutorial Overview

In the ISE/EDK tools, we’d use the Base System Builder to generate a base project for a particular hardware platform. Now with Vivado, the process is a little different but we have more control in how things are setup and we still benefit from some powerful automation features. In this tutorial we’ll create a base design for the Zynq in Vivado and we’ll use the MicroZed board as the hardware platform.

microzed

Requirements

Before following this tutorial, you’ll need the following:

  • Vivado 2014.2
  • MicroZed
  • Platform Cable USB II (or equivalent JTAG programmer)

Create a new Vivado project

Follow these steps to create a new project in Vivado:

  1. Open Vivado. From the welcome screen, click “Create New Project”.fpga_developer_20140731_090803
  2. Specify a folder for the project. I’ve created a folder named “microzed_custom_ip”. Click “Next”.fpga_developer_20140731_090921
  3. For the Project Type window, choose “RTL Project”. Click “Next”.fpga_developer_20140731_091123
  4. For the Add Sources window, click “Next”. We will add our multiplier source code later.
  5. For the Add Existing IP window, click “Next”.
  6. For the Add Constraints window, click “Next”.
  7. For the Default Part window, select the “MicroZed Board” and click “Next”.fpga_developer_20140731_091302
  8. Click “Finish” to complete the new project wizard.

 

Setup the Zynq PS

The new Vivado project starts off blank, so to create a functional base design, we need to at least add the Zynq PS (processor system) and make the minimal required connections. Follow these steps to add the PS to the project:

  1. From the Vivado Flow Navigator, click “Create Block Design”.fpga_developer_20140731_092018
  2. Specify a name for the block design. Let’s go with the default “design_1” and leave it local to the project. Click “OK”.fpga_developer_20140731_092055
  3. In the Block Design Diagram, you will see a message that says “This design is empty. To get started, Add IP from the catalog.”. Follow this advice by clicking on the blue “Add IP” link, or by using the “Add IP” icon.fpga_developer_20140731_092511
  4. The IP catalog should appear. Go to the end of the list and double click on the block named “ZYNQ7 Processing System” – it should be the second last on the list. Vivado will now add the PS to the block diagram.fpga_developer_20140731_092548
  5. In the Block Design Diagram, you will see a message that says “Designer Assistance available. Run Block Automation”. Click on the “Run Block Automation” link and select “processing_system7_0” from the drop-down menu. Block Automation makes connections and pin assignments to external hardware such as the DDR and fixed IO. It does this using the board definition of the hardware platform you specified when you created the project (MicroZed). We could make these connections ourselves if we were using a custom board, but for off-the-shelf boards, Block Automation makes the process a lot easier.fpga_developer_20140731_092844
  6. In the Block Automation window, make sure “Apply Board Preset” is ticked and click “OK”.fpga_developer_20140731_092950
  7. Now our block diagram has changed and we can see that the DDR and FIXED_IO are connected externally. Now the only remaining connection to make is the clock that we will use for the AXI buses. We must configure the Zynq to generate a clock and enable a general purpose AXI bus. To make these settings, double click on the Zynq PS block.fpga_developer_20140731_094013
  8. The Re-customize IP window will open. From the Page Navigator, select “Clock Configuration” and open the “PL Fabric Clocks” tree.fpga_developer_20140731_094152
  9. Make sure that the FCLK_CLK0 is enabled (ticked) and that it is set for a frequency of 100MHz. This will be our AXI clock.
  10. Now from the Page Navigator, select “PS-PL Configuration” and open the “GP Master AXI Interface” tree.
  11. Tick the “M AXI GP0 interface” checkbox to enable it.fpga_developer_20140731_094501
  12. Now click “OK” to close the Re-customize IP window.
  13. You should now see a new input port on the left side of the Zynq PS block. This is the AXI clock input. fpga_developer_20140731_094556We must now connect the FCLK_CLK0 output to the AXI clock input. To do this, click on the FCLK_CLK0 output and then click on the M_AXI_GP0_ACLK input. This will trace a wire between the pins and make the connection.fpga_developer_20140731_094805

Create the HDL wrapper

Now the Zynq is setup and all we need to do to create a functional project is to create a HDL wrapper for the design.

  1. Open the “Sources” tab from the Block Design window.fpga_developer_20140731_095715
  2. Right-click on “design_1” and select “Create HDL wrapper” from the drop-down menu.fpga_developer_20140731_095854
  3. From the “Create HDL wrapper” window, select “Let Vivado manage wrapper and auto-update”. Click “OK”.fpga_developer_20140731_095925

From this point, we have a base design containing the Zynq PS from which we could generate a bitstream and test on the MicroZed. We haven’t exploited any of the FPGA fabric, but the Zynq PS is already connected to the Gigabit Ethernet PHY, the USB PHY, the SD card, the UART port and the GPIO, all thanks to the Block Automation feature. So there is already quite a lot we could do with the design at this point, such as running Linux on the PS or running a bare metal application on it.

 

Generate the bitstream

To generate the bitstream, click “Generate Bitstream” in the Flow Navigator.fpga_developer_20140731_102843

Once the bitstream is generated, the following window appears. Select “Open Implemented Design” and click “OK”.

fpga_developer_20140731_140352

The implemented design will open in Vivado showing you a map of the Zynq device and how the design has been placed. In our case, we haven’t used any of the FPGA fabric (only the PS), so the map is empty for the most part.

fpga_developer_20140731_140739

Export the hardware to SDK

Once the bitstream has been generated, the hardware design is done and we’re ready to develop the code to run on the processor. This part of the design process is done in Xilinx Software Development Kit (SDK), so from Vivado we must first export the project to SDK.

  1. In Vivado, from the File menu, select “Export->Export hardware”.fpga_developer_20140731_141646
  2. In the window that appears, tick “Include bitstream” and click “OK”.fpga_developer_20140731_141701
  3. Again from the File menu, select “Launch SDK”.fpga_developer_20140731_141342
  4. In the window that appears, use the following settings and click “OK”.fpga_developer_20140731_141357

At this point, the SDK loads and a hardware platform specification will be created for your design. You should be able to see the hardware specification in the Project Explorer of SDK as shown in the image below.

fpga_developer_20140731_142739

You are now ready to create a software application to run on the PS.

 

Create a Software application

At this point, your SDK window should look somewhat like this:

fpga_developer_20140731_143202

To demonstrate creating an application for the Zynq, we’ll create a hello world application that will send “hello world” out the UART and to our PC.

  1. From the File menu, select New->Application Project.fpga_developer_20140731_143442
  2. In the first page of the New Project wizard, choose a name for the application. I’ve chosen “hello_world”. Click “Next”.fpga_developer_20140731_143532
  3. On the templates page, select the “Hello World” template and click “Finish”.fpga_developer_20140731_143654
  4. The SDK will generate a new application which you should find in the Project Explorer as in the image below.fpga_developer_20140731_151916

The “hello_world” folder contains the software application, which you can browse and modify. I suggest you take a look at the code that is contained here and get familiar with it.

The “hello_world_bsp” folder contains the Board Support Package, which is a bunch of libraries that are provided for accessing the various peripherals and features of the Zynq. In general, it’s better not to modify this code because it gets written over every time you use the “Clean project” option. Instead, if you want to make customizations, try to keep it in the application folder.

Once the software application has been created, it is automatically built. Once the application is built, we are ready to test the design on hardware.

Test the design on the hardware

To test the design, we are using the MicroZed board from Avnet. Make the following setup before continuing:

  1. On the MicroZed, set the JP1, JP2 and JP3 jumpers all to the 1-2 position.fpga_developer_20140731_144826
  2. Connect the USB-UART (J2) to a USB port of your PC.
  3. Connect a Platform Cable USB II programmer (or similar device) to the JTAG connector. Connect the programmer to a USB port of your PC.setup

 

Now you need to open up a terminal program on your PC and set it up to receive the “hello world” message. I use Miniterm because I’m a Python fan, but you could use any other terminal program such as Putty. Use the following settings:

  • Comport – check your device manager to find out what comport the MicroZed popped up as. In my case, it was COM12 as shown below.fpga_developer_20140731_150007
  • Baud rate: 115200bps
  • Data: 8 bits
  • Parity: None
  • Stop bits: 1

Now that your PC is ready to receive the “hello world” message, we are ready to send our bitstream and software application to the hardware.

  1. In the SDK, from the menu, select Xilinx Tools->Program FPGA.fpga_developer_20140731_150413
  2. In the Program FPGA window, we select the hardware platform to program. We have only one hardware platform, so click “Program”.fpga_developer_20140731_150540
  3. The bitstream will be loaded onto the Zynq and we are ready to load the software application. Select the “hello_world” folder in the Project Explorer, then from the menu, select Run->Run.fpga_developer_20140731_150759
  4. In the Run As window, select “Launch on Hardware (GDB)” and click “OK”.fpga_developer_20140731_150845
  5. The application will be loaded on the Zynq PS and it will be executed. Look out for the “Hello World” message in your terminal window!

fpga_developer_20140731_151052

What now?

In the following tutorials I’ll go through more concepts such as:

  • Creating a custom IP block and integrating your own HDL code
  • Using the DMA engine for transferring data between IP and memory
  • Running Linux on the PS
  • Accessing IP through a Linux application

Source code

The TCL build script and source code for this project is shared on Github here:

https://github.com/fpgadeveloper/microzed-base

For instructions on rebuilding the project from sources, read my post on version control for Vivado projects.

 

Version control for Vivado projects

$
0
0

Vivado generates a whole bunch of files when you create a project, and it’s not very clear on which are source files and which are generated files. The best approach is to consider them all to be generated files and to put none of them in version control. Instead, create a folder stucture for your sources that makes sense to you and use Tcl scripts to build the project and import the sources.

Vivado was designed to be completely Tcl driven. When you work in the GUI, you’ll probably notice that everything you do launches a Tcl command in the Tcl console at the bottom of the screen. This was a really nice design choice by Xilinx because it allows us to control the tools from scripts, thus allowing automation and proper version control.

Now just because we use scripts for good version control, doesn’t mean we have to give up the GUI. Vivado lets you generate a project from a script, work on it from the GUI and then save the project to a Tcl script form. It sounds simple, and it is, there are just a few things to understand first.

Example folder structure

Determine the folder/file structure that you want to use for the version controlled files. Here is the folder/file structure that I use for the designs that I put on Github (folders are in bold font):

  • Vivado
    • ip_repo
    • src
      • bd
        • design_1.tcl
      • hdl
    • build.tcl
    • build.bat

I call the top level folder Vivado to group together all the source files related to the Vivado project (some of my project repositories also have a folder for Python applications, EDK projects, etc). The “build.tcl” file is a Tcl script that will build the Vivado project from the sources. The “build.bat” file is a batch file that launches the build script. The “src” folder contains all the version controlled sources, such as VHDL and Verilog code, as well as scripts for generating parts of the project. The “bd” folder contains a script that generates the block design and is called from the “build.tcl” script. The “ip_repo” folder is generated by Vivado and contains version controlled sources for IP blocks used in the design.

How to generate a build script for a Vivado project

A template script for building a Vivado project can be generated from the GUI.

  1. Assuming you’ve created a project using the GUI – from the File menu, select ‘Write Project Tcl’.fpga_developer_20140801_150413
  2. Choose a name and location for the output Tcl script file. I generally use the name ‘build.tcl’ and locate it in the project folder.fpga_developer_20140801_150501

Now modify the build script!

The template script that is generated by Vivado serves as a good example, however it makes a few assumptions that don’t fit with the typical way you’d use a version controlled repository:

  1. The script assumes you want to create the project in the working directory (ie. the folder from which Vivado was run) and not the folder containing the build script. We’d typically want to check-out the sources in a new folder, run the build script and have the project generated in the new folder.
  2. The script assumes that you’ve version controlled the HDL wrapper and the block design (.bd) file, AND that they will be found at the same locations that Vivado put them in the original project. This doesn’t work if you want to regenerate the project in the folder containing the build script, because if your repository contains these files, located exactly as they were in the original project, the script fails, saying that the project files already exist. To make things worse, when it opens the block design (.bd) file, it modifies the date in the file, thus bringing it out of sync with version control when no design modification was actually made.

So the way around the first assumption is to replace these lines:

# Set the reference directory for source file relative paths
set origin_dir "."

# Set the directory path for the original project from where this script was exported
set orig_proj_dir "[file normalize "$origin_dir/orig-project"]"

# Create project
create_project myproject ./myproject

With these:

# Set the reference directory to where the script is
set origin_dir [file dirname [info script]]

# Create project
create_project myproject $origin_dir/myproject

The way around the second assumption is to generate the block design and the wrapper from a script.

Fortunately, we don’t have to write the script to generate the block design, Vivado can make the script for us. To generate the block design script in Vivado, with the block design open, select File->Export->Export block design.

fpga_developer_20140804_144504

Save this file in the “src/bd” folder and commit it to version control.

Now we can modify the “build.tcl” script to call the block design script and generate the HDL wrapper. At the end of the file, add the following lines:

# Create block design
 source $origin_dir/src/bd/design_1.tcl

 # Generate the wrapper
 set design_name [get_bd_designs]
 make_wrapper -files [get_files $design_name.bd] -top -import

Finally, you’ll have to remove the lines that import the HDL wrapper file and the block design (.bd) file into the project.

What files to commit to version control

In general, don’t commit anything within the project sub-folder that was created by Vivado. You want to keep ALL controlled sources including scripts out of that folder.

  1. Commit “build.tcl” (discussed above) to version control.
  2. Commit “src/bd/design_1.bd” (discussed above) to version control.
  3. If you added any other sources to the design such as VHDL or Verilog files, make sure they are located in the “src/hdl” folder and commit these as well.
  4. If you created custom IP, you can commit all the files in the IP repository (ip_repo). The ip_repo folder should be at the same level as your “src” folder.

How to rebuild a Vivado project from the build script and sources

These steps assume that you’ve cloned the project repository to a new location (otherwise Vivado will try to regenerate the project files that already exist and it’ll produce an error message).

My preferred method is to run a batch file called “build.bat” that I commit to version control in the same location as the “build.tcl” file. The batch file should contain the following line:

C:\Xilinx\Vivado\2014.2\bin\vivado.bat -mode batch -source build.tcl

So from Windows Explorer I only need to double click on that batch file and Vivado generates the project files. Then I open the project in Vivado by double clicking on the generated .xpr file.

Just for completeness, here is one way to call the script from Vivado:

  1. From the welcome screen in Vivado, select Window->Tcl Console.fpga_developer_20140801_151113
  2. The Tcl console should open up at the bottom of the welcome screen.fpga_developer_20140801_151205
  3. In the Tcl console, where it says ‘Type a Tcl command here’, type the command ‘cd <location-of-your-project>’ and press ENTER to change the working directory to that of your project (the location of the build.tcl file).fpga_developer_20140801_151446
  4. Then in the Tcl console, type the command ‘source build.tcl’ and press ENTER to execute the build script.fpga_developer_20140801_151552

Vivado will then regenerate the project files and open them in the GUI.

Dealing with modifications

When you make modifications to the project using the GUI, always remember to save them by using the “Tools->Write Project Tcl” and “File->Export->Export block design” options.

Need an example?

For an example of how to version control a Vivado project, checkout this base system project that I’ve shared on Github:

https://github.com/fpgadeveloper/microzed-base

 

 

 

Creating a custom IP block in Vivado

$
0
0

Tutorial Overview

In this tutorial we’ll create a custom AXI IP block in Vivado and modify its functionality by integrating custom VHDL code. We’ll be using the Zynq SoC and the MicroZed as a hardware platform. For simplicity, our custom IP will be a multiplier which our processor will be able to access through register reads and writes over an AXI bus.

The multiplier takes in two 16 bit unsigned inputs and outputs one 32 bit unsigned output. A single 32 bit write to the IP will contain the two 16 bit inputs, separated by the lower and higher 16 bits. A single 32 bit read from the peripheral will contain the result from the multiplication of the two 16 bit inputs. The design doesn’t serve much purpose, but it is a good example of integrating your own code into an AXI IP block.

 

Requirements

Before following this tutorial, you will need to do the following:

  • Vivado 2014.2
  • MicroZed
  • Platform Cable USB II (or equivalent JTAG programmer)

Start from a base project

You can do this tutorial with any existing Vivado project, but I’ll start with the base system project for the MicroZed that you can access here:

Base system project for the MicroZed

 

Create the Custom IP

  1. With the base Vivado project opened, from the menu select Tools->Create and package IP.fpga_developer_20140802_132119
  2. The Create and Package IP wizard opens. If you are used to the ISE/EDK tools you can think of this as being similar to the Create/Import Peripheral wizard. Click “Next”.fpga_developer_20140802_132203
  3. On the next page, select “Create a new AXI4 peripheral”. Click “Next”.fpga_developer_20140802_132323
  4. Now you can give the peripheral an appropriate name, description and location. Click “Next”.fpga_developer_20140802_132426
  5. On the next page we can configure the AXI bus interface. For the multiplier we’ll use AXI lite, and it’ll be a slave to the PS, so we’ll stick with the default values.fpga_developer_20140802_132638
  6. On the last page, select “Edit IP” and click “Finish”. Another Vivado window will open which will allow you to modify the peripheral that we just created.fpga_developer_20140802_132901

fpga_developer_20140802_133817

At this point, the peripheral that has been generated by Vivado is an AXI lite slave that contains 4 x 32 bit read/write registers. We want to add our multiplier code to the IP and modify it so that one of the registers connects to the multiplier inputs and another to the multiplier output.

Add the multiplier code to the peripheral

You can find the multiplier code on Github at the link below. Download the “multiplier.vhd” file and save it somewhere, the location is not important for now.

https://github.com/fpgadeveloper/microzed-custom-ip/blob/master/ip_repo/my_multiplier_1.0/src/multiplier.vhd

Note that these steps must be done in the Vivado window that contains the peripheral we just created (not the base project).

  1. From the Flow Navigator, click “Add Sources”.fpga_developer_20140802_133852
  2. In the window that appears, select “Add or Create Design Sources” and click “Next”.fpga_developer_20140802_133929
  3. On the next window, click “Add Files”.fpga_developer_20140802_134008
  4. Browse to the “multiplier.vhd” file, select it and click “OK”.
  5. Make sure you tick “Copy sources into IP directory” and then click “Finish”.fpga_developer_20140802_134415

The multiplier code is now added to the peripheral, however we still have to instantiate it and connect it to the registers.

 

Modify the Peripheral

At this point, your Project Manager Sources window should look like the following:fpga_developer_20140802_134746

 

  1. Open the branch “my_multiplier_v1_0 – arch_imp”.fpga_developer_20140802_134843
  2. Double click on the “my_multiplier_v1_0_S00_AXI_inst” file to open it.
  3. The source file should be open in Vivado. Find the line with the “begin” keyword and add the following code just above it to declare the multiplier and the output signal:
signal multiplier_out : std_logic_vector(31 downto 0);
 
component multiplier
port (
  clk: in std_logic;
  a: in std_logic_VECTOR(15 downto 0);
  b: in std_logic_VECTOR(15 downto 0);
  p: out std_logic_VECTOR(31 downto 0));
end component;
  1. Now find the line that says “– Add user logic here” and add the following code below it to instantiate the multiplier:
multiplier_0 : multiplier
port map (
  clk => S_AXI_ACLK,
  a => slv_reg0(31 downto 16),
  b => slv_reg0(15 downto 0),
  p => multiplier_out);
  1. Find this line of code “reg_data_out <= slv_reg1;” and replace it with “reg_data_out <= multiplier_out;”.
  2. In the process statement just a few lines above, replace “slv_reg1” with “multiplier_out”.
  3. Save the file.
  4. You should notice that the “multiplier.vhd” file has been integrated into the hierarchy because we have instantiated it from within the peripheral.fpga_developer_20140802_140156
  5. Click on “IP File Groups” in the Package IP tab of the Project Manager.fpga_developer_20140802_140311
  6. Click the “Merge changes from IP File Group Wizard” link.fpga_developer_20140802_140409
  7. The “IP File Groups” should now have a tick.fpga_developer_20140802_140458
  8. Now click “Review and Package IP”.fpga_developer_20140802_140543
  9. Now click “Re-package IP”.fpga_developer_20140802_140613

The peripheral will be packaged and the Vivado window for the peripheral should be automatically closed. We should now be able to find our IP in the IP catalog. Now the rest of this tutorial will be done from the original Vivado window.

 

Add the IP to the design

  1. Click the “Add IP” icon.fpga_developer_20140802_140806
  2. Find the “my_multiplier” IP and double click it.fpga_developer_20140802_140927
  3. The block should appear in the block diagram and you should see the message “Designer Assistance available. Run Connection Automation”. Click the connection automation link.fpga_developer_20140802_141012
  4. Click the “my_multiplier_0” peripheral from the drop-down menu.fpga_developer_20140802_141113
  5. In the window that appears, set Clock connection to “Auto” and click “OK”.fpga_developer_20140802_141148
  6. The new block diagram should look like this:fpga_developer_20140802_141316
  7. Generate the bitstream.fpga_developer_20140802_141409
  8. When the bitstream is generated, select “Open the implemented design” and click “OK”.fpga_developer_20140802_142049

 

Export the hardware design to SDK

Once the bitstream has been generated, we can export our design to SDK where we can then write code for the PS. The PS is going to write data to our multiplier and read back the result.

  1. In Vivado, from the File menu, select “Export->Export hardware”.fpga_developer_20140731_141646
  2. In the window that appears, tick “Include bitstream” and click “OK”.fpga_developer_20140731_141701
  3. Again from the File menu, select “Launch SDK”.fpga_developer_20140731_141342
  4. In the window that appears, use the following settings and click “OK”.fpga_developer_20140731_141357

At this point, the SDK loads and a hardware platform specification will be created for your design. You should be able to see the hardware specification in the Project Explorer of SDK as shown in the image below.

fpga_developer_20140731_142739

You are now ready to create a software application to run on the PS.

 

Create a Software application

At this point, your SDK window should look somewhat like this:

fpga_developer_20140731_143202

To make things easy for us, we’ll use the template for the hello world application and then modify it to test the multiplier.

  1. From the File menu, select New->Application Project.fpga_developer_20140731_143442
  2. In the first page of the New Project wizard, choose a name for the application. I’ve chosen “hello_world”. Click “Next”.fpga_developer_20140731_143532
  3. On the templates page, select the “Hello World” template and click “Finish”.fpga_developer_20140731_143654
  4. The SDK will generate a new application which you should find in the Project Explorer as in the image below.fpga_developer_20140731_151916

The “hello_world” folder contains the Hello World software application, which we will modify to test our multiplier.

Modify the Software Application

Now all we need to do is modify the software application to test our multiplier peripheral.

  1. From the Project Explorer, open the “hello_world/src” folder. Open the “helloworld.c” source file.
  2. Replace all the code in this file with the following.

 

#include "platform.h"
#include "xbasic_types.h"
#include "xparameters.h"

Xuint32 *baseaddr_p = (Xuint32 *)XPAR_MY_MULTIPLIER_0_S00_AXI_BASEADDR;

int main()
{
init_platform();

xil_printf("Multiplier Test\n\r");

// Write multiplier inputs to register 0
*(baseaddr_p+0) = 0x00020003;
xil_printf("Wrote: 0x%08x \n\r", *(baseaddr_p+0));

// Read multiplier output from register 1
xil_printf("Read : 0x%08x \n\r", *(baseaddr_p+1));

xil_printf("End of test\n\n\r");

return 0;
}

 

 

Save and close the file.

Test the design on the hardware

To test the design, we are using the MicroZed board from Avnet. Make the following setup before continuing:

  1. On the MicroZed, set the JP1, JP2 and JP3 jumpers all to the 1-2 position.fpga_developer_20140731_144826
  2. Connect the USB-UART (J2) to a USB port of your PC.
  3. Connect a Platform Cable USB II programmer (or similar device) to the JTAG connector. Connect the programmer to a USB port of your PC.setup

 

Now you need to open up a terminal program on your PC and set it up to receive the test messages. I use Miniterm because I’m a Python fan, but you could use any other terminal program such as Putty. Use the following settings:

  • Comport – check your device manager to find out what comport the MicroZed popped up as. In my case, it was COM12 as shown below.fpga_developer_20140731_150007
  • Baud rate: 115200bps
  • Data: 8 bits
  • Parity: None
  • Stop bits: 1

Now that your PC is ready to receive the test messages, we are ready to send our bitstream and software application to the hardware.

  1. In the SDK, from the menu, select Xilinx Tools->Program FPGA.fpga_developer_20140731_150413
  2. In the Program FPGA window, we select the hardware platform to program. We have only one hardware platform, so click “Program”.fpga_developer_20140731_150540
  3. The bitstream will be loaded onto the Zynq and we are ready to load the software application. Select the “hello_world” folder in the Project Explorer, then from the menu, select Run->Run.fpga_developer_20140731_150759
  4. In the Run As window, select “Launch on Hardware (GDB)” and click “OK”.fpga_developer_20140731_150845
  5. The application will be loaded on the Zynq PS and it will be executed. Look out for the results in your terminal window!

fpga_developer_20140802_144225

We’re sending two 16-bit inputs 0×02 and 0×03 and the result is 0×06 as expected.

Source code

The TCL build script and source code for this project is shared on Github here:

https://github.com/fpgadeveloper/microzed-custom-ip

For instructions on rebuilding the project from sources, read my post on version control for Vivado projects.

Using the AXI DMA in Vivado

$
0
0

In a previous tutorial I went through how to use the AXI DMA Engine in EDK, now I’ll show you how to use the AXI DMA in Vivado. We’ll create the hardware design in Vivado, then write a software application in the Xilinx SDK and test it on the MicroZed board (source code is shared on Github for the MicroZed and the ZedBoard, see links at the bottom).

What is DMA?

DMA stands for Direct Memory Access and a DMA engine allows you to transfer data from one part of your system to another. The simplest usage of a DMA would be to transfer data from one part of the memory to another, however a DMA engine can be used to transfer data from any data producer (eg. an ADC) to a memory, or from a memory to any data consumer (eg. a DAC).

Tutorial overview

In this design, we’ll use the DMA to transfer data from memory to an IP block and back to the memory. In principle, the IP block could be any kind of data producer/consumer such as an ADC/DAC FMC, but in this tutorial we will use a simple FIFO to create a loopback. After, you’ll be able to break the loop and insert whatever custom IP you like.

fpga_developer_20140806_130447The block diagram above illustrates the design that we’ll create. The processor and DDR memory controller are contained within the Zynq PS. The AXI DMA and AXI Data FIFO are implemented in the Zynq PL. The AXI-lite bus allows the processor to communicate with the AXI DMA to setup, initiate and monitor data transfers. The AXI_MM2S and AXI_S2MM are memory-mapped AXI4 buses and provide the DMA access to the DDR memory. The AXIS_MM2S and AXIS_S2MM are AXI4-streaming buses, which source and sink a continuous stream of data, without addresses.

Notes:

  • MM2S stands for Memory-Mapped to Streaming, whereas S2MM stands for Streaming to Memory-Mapped.
  • When Scatter-Gather is used, there is an extra AXI bus between the DMA and the memory controller. It was left out of the diagram for simplicity.

Requirements

Before following this tutorial, you will need to do the following:

  • Vivado 2014.2
  • MicroZed
  • Platform Cable USB II (or equivalent JTAG programmer)

 Start from the base project

We’ll start this tutorial with the base system project for the MicroZed that you can access here:

Base system project for the MicroZed

Add the AXI DMA

  1. Open the base project in Vivado.
  2. In the Flow Navigator, click ‘Open Block Design’.fpga_developer_20140806_093459
  3. The block diagram should open and you should only have the Zynq PS in the design.
  4. Click the ‘Add IP’ icon and double click ‘AXI Direct Memory Access’ from the catalog.fpga_developer_20140806_093726

Connect the Memory-mapped AXI buses

  1. The DMA block should appear and designer assistance should be available. Click the ‘Run Connection Automation’ link and select ‘/axi_dma_0/S_AXI_LITE’ from the drop-down menu.fpga_developer_20140806_093807
  2. Click ‘OK’ in the window that appears. Vivado will connect the AXI-lite bus of the DMA to the General Purpose AXI Interconnect of the PS.fpga_developer_20140806_093915
  3. Your block diagram should now look like this :fpga_developer_20140806_094158
  4. Now we need to connect AXI buses M_AXI_SG, M_AXI_MM2S and M_AXI_S2MM of the DMA to a high performance AXI slave interface on the PS. Our PS doesn’t seem to have a high-performance AXI slave interface, so we need to change the Zynq configuration to enable one. Double click on the Zynq block.fpga_developer_20140806_094514
  5. Select ‘PS-PL Configuration’, open the ‘HP Slave AXI Interface’ branch and tick the ‘S AXI HP0 interface’ to enable it. Then click OK.fpga_developer_20140806_094801
  6. The high-performance AXI slave ports should now be visible in the block diagram, and designer assistance should be available. Click the ‘Run Connection Automation’ link and select ‘/processing_system7_0/S_AXI_HP0’ from the drop-down menu.fpga_developer_20140806_094907
  7. In the window that appears, make sure that Vivado intends to connect it to the DMA and click OK.fpga_developer_20140806_094955
  8. Designer assistance should again be available, click the ‘Run Connection Automation’ link and select ‘/axi_dma_0/M_AXI_SG’ from the drop-down menu.fpga_developer_20140806_095158
  9. In the window that appears, click OK.fpga_developer_20140806_095250
  10. Designer assistance should still be available, click the ‘Run Connection Automation’ link and select ‘/axi_dma_0/M_AXI_S2MM’ from the drop-down menu.fpga_developer_20140806_095330
  11. In the window that appears, click OK.fpga_developer_20140806_095341

 

Now all the memory-mapped AXI buses are connected to the DMA. Now we only have to connect the AXI streaming buses to our loopback FIFO and connect the DMA interrupts.

Add the FIFO

  1. Click the ‘Add IP’ icon and double click ‘AXI4-Stream Data FIFO’ from the catalog.fpga_developer_20140806_100426
  2. The FIFO should be visible in the block diagram. Now we must connect the AXI-streaming buses to those of the DMA. Click the ‘S_AXIS’ port on the FIFO and connect it to the ‘M_AXIS_MM2S’ port of the DMA.fpga_developer_20140806_100702
  3. Then connect the ‘M_AXIS’ port on the FIFO and connect it to the ‘S_AXIS_S2MM’ port of the DMA.fpga_developer_20140806_100752
  4. Now we must connect the FIFO clock and reset. Click the ‘s_axis_aresetn’ port of the FIFO and connect it to the ‘axi_resetn’ port of the DMA.fpga_developer_20140806_100937
  5. Click the ‘s_axis_aclk’ port of the FIFO and connect it to the ‘s_axi_lite_aclk’ port of the DMA.fpga_developer_20140806_101026

Remove the AXI-Streaming status and control ports of the DMA

In our design, we won’t need the AXI-Streaming status and control ports which are used to transmit extra information alongside the data stream. You might use them if you were connecting to the AXI Ethernet core or a custom IP that made use of them.

  1. In the block diagram, double click the AXI DMA block.
  2. Un-tick the ‘Enable Control / Status Stream’ option and click OK.fpga_developer_20140806_101151

Connect the DMA interrupts to the PS

Our software application will test the DMA in polling mode, but to be able to use it in interrupt mode, we need to connect the interrupts ‘mm2s_introut’ and ‘s2mm_introut’ to the Zynq PS.

  1. First we have to enable interrupts from the PL. Double click the Zynq block and select the Interrupts tab.fpga_developer_20140806_101640
  2. Tick ‘Fabric Interrupts’ and ‘IRQ_F2P[15 :0]’ to enable them, and click OK.
  3. Click the ‘Add IP’ icon and double-click ‘Concat’ from the catalog.fpga_developer_20140806_101815
  4. Connect the ‘dout’ port of the Concat to the ‘IRQ_F2P’ port of the Zynq PS.fpga_developer_20140806_101931
  5. Connect the ‘mm2s_introut’ port of the DMA to the ‘In0’ port of the Concat.fpga_developer_20140806_102044
  6. Connect the ‘s2mm_introut’ port of the DMA to the ‘In1’ port of the Concat.fpga_developer_20140806_102104

Validate and build the design

  1. From the menu select Tools->Validate Design.fpga_developer_20140806_102240
  2. You should get this message saying that validation was successful.fpga_developer_20140806_102337
  3. We can clean up the block diagram by clicking the Regenerate Layout icon.fpga_developer_20140806_102434
  4. Our block diagram now looks like this :fpga_developer_20140806_102715
  5. In the Flow Navigator, click ‘Generate Bitstream’.fpga_developer_20140806_102753

 

Export the hardware design to SDK

Once the bitstream has been generated, we can export our design to SDK where we can develop the software application that will setup a DMA transfer, wait for completion and then verify the loopback.

  1. In Vivado, from the File menu, select “Export->Export hardware”.fpga_developer_20140731_141646
  2. In the window that appears, tick “Include bitstream” and click “OK”.fpga_developer_20140731_141701
  3. Again from the File menu, select “Launch SDK”.fpga_developer_20140731_141342
  4. In the window that appears, use the following settings and click “OK”.fpga_developer_20140731_141357

At this point, the SDK loads and a hardware platform specification will be created for your design. You should be able to see the hardware specification in the Project Explorer of SDK as shown in the image below.

fpga_developer_20140731_142739

We are now ready to create the software application.

Create a Software application

At this point, your SDK window should look somewhat like this:

fpga_developer_20140731_143202

To make things easy for us, we’ll use the template for the hello world application and then modify it to test the AXI DMA.

  1. From the File menu, select New->Application Project.fpga_developer_20140731_143442
  2. In the first page of the New Project wizard, choose a name for the application. I’ve chosen “hello_world”. Click “Next”.fpga_developer_20140731_143532
  3. On the templates page, select the “Hello World” template and click “Finish”.fpga_developer_20140731_143654
  4. The SDK will generate a new application which you should find in the Project Explorer as in the image below.fpga_developer_20140731_151916

The “hello_world” folder contains the Hello World software application, which we will modify to test our AXI DMA.

Modify the Software Application

We need to modify the hello world software application to test our DMA.

  1. From the Project Explorer, open the “hello_world/src” folder. Open the “helloworld.c” source file.
  2. Replace all the code in this file with the code that you will find on Github here: https://github.com/fpgadeveloper/microzed-axi-dma/blob/master/SDK/hello_world/src/helloworld.c
  3. Save and close the file. The application should build automatically.

The application source code is derived from an example provided by Xilinx in the installation files. You can find it at this location on your PC:

C:\Xilinx\14.7\ISE_DS\EDK\sw\XilinxProcessorIPLib\drivers\axidma_v7_02_a\examples\xaxidma_example_sg_poll.c

By the way, if you didn’t know about it already, that folder contains heaps of examples that you will find useful, I suggest you check it out.

Test the design on the hardware

To test the design, we are using the MicroZed board from Avnet. Make the following setup before continuing:

  1. On the MicroZed, set the JP1, JP2 and JP3 jumpers all to the 1-2 position.fpga_developer_20140731_144826
  2. Connect the USB-UART (J2) to a USB port of your PC.
  3. Connect a Platform Cable USB II programmer (or similar device) to the JTAG connector. Connect the programmer to a USB port of your PC.setup

 

Now you need to open up a terminal program on your PC and set it up to receive the test messages. I use Miniterm because I’m a Python fan, but you could use any other terminal program such as Putty. Use the following settings:

  • Comport – check your device manager to find out what comport the MicroZed popped up as. In my case, it was COM12 as shown below.fpga_developer_20140731_150007
  • Baud rate: 115200bps
  • Data: 8 bits
  • Parity: None
  • Stop bits: 1

Now that your PC is ready to receive the test messages, we are ready to send our bitstream and software application to the hardware.

  1. In the SDK, from the menu, select Xilinx Tools->Program FPGA.fpga_developer_20140731_150413
  2. In the Program FPGA window, we select the hardware platform to program. We have only one hardware platform, so click “Program”.fpga_developer_20140731_150540
  3. The bitstream will be loaded onto the Zynq and we are ready to load the software application. Select the “hello_world” folder in the Project Explorer, then from the menu, select Run->Run.fpga_developer_20140731_150759
  4. In the Run As window, select “Launch on Hardware (GDB)” and click “OK”.fpga_developer_20140731_150845
  5. The application will be loaded on the Zynq PS and it will be executed. Look out for the results in your terminal window!fpga_developer_20140806_122245

 

Source code

The TCL build script and source code for this project is shared on Github at the following links:

For instructions on rebuilding the project from sources, read my post on version control for Vivado projects.

A first look at a first product

$
0
0

After years designing products for other companies, I’ve finally designed something for my own company.

If you have a ZedBoard and you want to experiment with MGTs, now you can with my two new SERDES low-pin-count FMCs. Both boards use the DS32EL0421/DS32EL0124 serializer/deserializer devices from Texas Instruments to provide two external multi-gigabit transceivers from any standard FMC carrier regardless of whether the FPGA has internal MGTs or not. The external MGTs can transmit and receive data up to 2.5Gbps with DC-balance encoding (8b/10b) or up to 3.125Gbps without DC-balance encoding.

The first FMC is designed to accept SFP modules for Gigabit Ethernet and optical applications. The second FMC is designed with SATA connectors to provide a convenient way to connect to the MGTs in custom applications, or for connection to SATA HDDs.

serdes-sfp-fmc-altium

serdes-sata-fmc-altium

I’ll have the first prototypes in a couple of weeks and I’ll be sure to post photos when they arrive. I’m going to provide the schematics for download on the product page, and I’ll provide all the support code and example designs for download on Github.

If you’re interested in purchasing the SERDES FMCs or you want to know more, please contact me.

There’ll be more to come…

Since I started my consulting business, my goal has always been to eventually make the transition to a product based business. Don’t get me wrong, I love consulting work and I wont give that up – but I’ve got my own ideas and I think I can contribute to FPGA technology in my own unique way. I want to keep doing cool things with FPGAs, do it openly and in a way that promotes learning and stimulates interest. That’s my line in the sand.

PCBs for the SERDES FMC

$
0
0

Yesterday I received the bare PCBs for the SERDES SFP FMC, my new product that enables 2 multi-gigabit transceivers on the ZedBoard or other LPC FMC carriers that don’t have internal MGTs.

In the last couple of weeks I’ve been working hard on a demo design in Vivado which you can find on Github here:

https://github.com/fpgadeveloper/zedboard-serdes-sfp-fmc

So far all timing passes at the board’s top speed of 3.125Gbps (or 2.5Gbps with DC balanced encoding).

Here are a couple photos of the boards:

serdes-sfp-fmc-pcb

serdes-sfp-fmc-pcb-bot

I’ve got to say that it feels great to share my work like this. One of the downsides of client work is that I don’t own the IP and its almost always confidential so I can’t share too many details about what I’m doing on my blog. Now it’s my product, my IP, and I decide how much of it I can share!

SERDES FMC first units

$
0
0

Here’s a peek at the first units of the SERDES FMCs, the first low pin-count FPGA Mezzanine Card to enable multi-gigabit transceivers on the ZedBoard and other FPGA boards that don’t have internal MGTs. The first board is designed for SFP modules for Ethernet and optical applications whereas the second board has SATA connectors for custom applications. Both boards are compliant to the VITA 57 standard.

Stay tuned for the performance results this week!

serdes-sfp-1serdes-sata-1

If you want more information on either board, don’t hesitate to contact me.


Introducing the Quad Gigabit Ethernet FMC

$
0
0

Here’s the next product in Opsero’s growing lineup of FPGA I/O cards: the Quad Gigabit Ethernet FMC. This low-pin-count FMC is loaded with four Marvell Gigabit Ethernet PHYs and enables FPGA networking applications on the ZedBoard and other LPC carriers. A demo design for the ZedBoard is available on Github at the link below and further demos will become available in the next few weeks:

https://github.com/fpgadeveloper/zedboard-qgige

Look out for more details including the technical specs, schematics and more on the soon to be launched product page.

 

quad-gige-1 quad-gige-2

If you want more information about the Quad Gigabit Ethernet FMC, or if you are interested in purchasing the board, please don’t hesitate to contact me.

Ethernet FMC is now available

$
0
0

Announcing that the new Ethernet FMC, a Quad Gigabit Ethernet FPGA Mezzanine Card (FMC) is now available to buy. The board is designed for easy integration with the ZedBoard, with open-source example designs so you can start designing your product sooner. The low-pin-count FMC features 4 Marvell PHYs, a 125MHz oscillator and a quad RJ45 with integrated magnetics.

The Ethernet FMC is compliant to the Vita 57.1 FMC standard except for its height (due to the RJ45 connector) and its length. The FMC is electrically and mechanically compatible with the ZedBoard and all the Xilinx evaluation boards.

Features:

  • 4 x Gigabit Ethernet ports
  • Vita 57.1 electrically compliant low-pin-count FMC
  • 125MHz clock oscillator
  • Example designs for the ZedBoard (Vivado)

Applications:

  • Gigabit Ethernet Switch
  • Ethernet Traffic Monitor
  • Latency Measurement
  • High-speed Congestion Control

Checkout the product page for more information.

quad-gige-small-3

Ethernet FMC first units shipped

$
0
0

Today I’m excited to announce that the first Ethernet FMCs were shipped! I would like to say thanks to all those who pre-ordered the Ethernet FMC, thanks for your patience and confidence and I hope the product enables you to develop new and exciting technologies in the networking space.

I’ve had an insanely busy last few weeks trying to organize the production of the boards, testing the boards, as well as working out the packaging, labeling and shipping materials. All the work in getting the product to a complete and clean-cut state has been much more time-consuming than I had ever imagined, but the learning experience was worth the effort many times over.

The response from the release was better than I had imagined, especially after the listing as an accessory on the ZedBoard page and the blog write-up by Xilinx. I had pre-orders from companies in the United States, France and Poland, and several other companies expressed their interest.

Now I’m working hard to get the Ethernet FMC to work with Linux and make some more example designs available.

If you’re interested in the Ethernet FMC, checkout the product page for more info!

 

Ethernet FMC supports Xilinx Dev Boards

$
0
0

Support for the Xilinx Series-7 development boards AC701, KC705, VC707, ZC702 and ZC706 has been added to the Ethernet FMC product page. Now you can use the Ethernet FMC on any one of these boards and support up to 8 x gigabit Ethernet ports! The KC705, VC707, ZC702 and ZC706 have two FMC connectors allowing you to plug in two Ethernet FMCs, enabling 8 independent ports.

Download the Vivado constraint files from the Docs section on the product page.

Ethernet FMC performance benchmarks released

$
0
0

One question I get a lot about the Ethernet FMC is: What is the maximum throughput? It’s a good question, so I created an example design to help me get the answer. The maximum throughput test design, that you can download on Github, uses four hardware packet generators (coded in VHDL) to feed the Ethernet MACs with back-to-back packets. These packets then get sent out of the Ethernet ports and get looped back into another Ethernet port through a CAT-5 cable. Here is the block diagram:

Ethernet FMC Maximum throughput test design

I hooked up port 0 to loopback to port 2, and port 1 to loopback to port 3. I setup ports 0 and 1, and ports 2 and 3 to operate on separate (asynchronous) clocks – this way I could be sure that the adjacent lanes were asynchronous to each other, and thus be better positioned to catch crosstalk induced errors on the RGMII traces on the Ethernet FMC.

The results: 97% channel efficiency and an impressive 974Mbps effective throughput per channel. No crosstalk-induced errors. Very happy indeed.

Checkout the results here: Ethernet FMC performance benchmarks

 

1.8V Version Ethernet FMC now available

$
0
0

I recently received and tested the first 1.8V Ethernet FMCs and they are now available to buy on ethernetfmc.com. There are two main reasons why you’d actually want a 1.8V version: Firstly, some carriers only support VADJ of 1.8V (such as the VC707 and VC709). Secondly, some customers need to match it with another 1.8V FMC on a dual-FMC carrier.

Releasing the new version didn’t come without headaches. Most FMC carriers on the market have a 2.5V VADJ by default, so there’s a good chance of frying the Ethernet PHYs on first go. Luckily I haven’t made that mistake yet! The other “problem” is the fact that the board provides a 125MHz LVDS clock – respecting the Vita 57 standard – but creating a problem for carriers with FMCs that route to HR (high-range) banks. Which is most of them! Yes the ZedBoard, AC701, KC705, ZC702 and ZC706 all route to HR banks. HR banks require you to define your LVDS I/Os with the LVDS_25 IO standard (ie. the 2.5V standard), but we’d really want to be using the LVDS (1.8V) IO standard. So I had to either declare non-compatibility or find a workaround. Fortunately, there is a workaround and I’ve written about it here:

Using the 1.8V version Ethernet FMC with the ZedBoard

So if you need an Ethernet FMC that works at 1.8V, now you can have it!

 

Comparison of Zynq SoMs

$
0
0

In the last year or so, there has been an explosion in the availability of System-on-Modules (SoMs) featuring the popular FPGA+ARM combo Zynq-7000 SoC from Xilinx. I’ve always promoted the idea that FPGAs and SoCs allow for faster design cycles and rapid proof-of-concept, but these SoMs take that advantage to another level. Let me explain why. In the past, I would handle most projects by doing a proof-of-concept on an evaluation board, then designing a custom board that integrates all the required components onto a single PCB. While this process is fairly straightforward and minimizes my risk in designing the final custom board, it still has its drawbacks:

  • Lack of appropriate FMCs. Sometimes the customer’s I/O needs can’t be satisfied by an off-the-shelf FMC, so a custom FMC must be developed. This means more time and money spent on a board that will not be used in the final product most of the time.
  • Eval boards are not customizable. Evaluation boards typically contain every peripheral imaginable, the problem being that they all connect to the FPGA and use up valuable I/Os that could have been used for something we actually needed. In most cases the customer only needs Ethernet, USB and an SD memory card.
  • Eval boards aren’t made to leave your desk. Apart from PCIe applications, eval boards typically don’t have a form factor that is small enough or rugged enough for testing in the field or in a product enclosure. Think of putting one in a drone, in a vehicle or in a camera housing – not happening.

My last point is the most important one because most companies these days want a proof-of-concept or a prototype that can be tested in the field or in their product enclosure. This usually isn’t possible with eval boards, but it often is with SoMs. The major advantage that SoMs have over eval boards is that they can be used to develop prototypes that are appropriate for the environment/enclosure in which they will be used. On top of that, some SoMs are manufactured in large quantities, have a good supply from reliable companies and can be seriously considered for use in the final product.

Here are some of the benefits of the SoMs when compared to evaluation and development boards:

  • They’re typically 10x cheaper ($50-$500 compared to $500-$5000)
  • They’re physically smaller, more rugged and more easily integrated into a product enclosure
  • They usually have better availability
  • They’re more easily adaptable to specialized needs

So let me describe a typical design experience with a SoM. My client wants an image processor with 16 image sensors connected to the Zynq-7000. I propose a Zynq SoM so that I can leverage all the work that has gone into the board design, plus kickstart the FPGA design with the provided code examples. I design a custom carrier for the SoM with 16 image sensors – the PCB is only 4-layers and is trivial because I don’t have to route an FPGA or DDR3 memory. In a short time, we have a working prototype that fits nicely into the product enclosure and the client can start putting it in front of customers. Going from here to the final product can take many paths, but the important thing is that my client now has something that is presentable to the market, and he got there with a minimum of delay and expense.

Here is my take on a few of the Zynq-7000 SoMs on the market at present.

 

MicroZed

Arguably the most popular Zynq SoM due to its affordability and being one of the first on the market in this space, the MicroZed from Avnet is a versatile SoM, great for integration into custom designs, but also can be useful as a stand-alone development board.

 

  • XC7Z010-1CLG400C
  • 1 GB of DDR3 SDRAM
  • 128 Mb of QSPI Flash
  • 10/100/1000 Ethernet
  • USB 2.0
  • USB-UART
  • 100 User I/O (50 per connector)
  • 2×6 Digilent Pmod® compatible interface providing 8 PS MIO connections for user I/O
  • User LED and push switch

microzed

 

 

PicoZed

Designed for better integration into custom designs, the PicoZed from Avnet is similar to their MicroZed product but they’ve basically pushed all the interfaces through the expansion connectors so that you only use what you need. This reduces the cost of the SoM and relaxes the mechanical constraints on your design because you choose where to put the bulky connectors. There is also a version of the PicoZed with gigabit transceivers.

 

  • XC7Z010 or XC7Z020 or XC7Z015 or XC7Z030
  • 1 GB of DDR3 SDRAM
  • 128 Mb of QSPI Flash
  • 4 GB eMMC
  • 10/100/1000 Ethernet PHY
  • USB 2.0 PHY
  • XC7Z010
    • 113 User I/O (100 PL, 13 PS MIO)
  • XC7Z020
    • 148 User I/O (135 PL, 13 PS MIO)
  • XC7Z015
    • 138 User I/O (125 PL, 13 PS MIO)
  • XC7Z030
    • 148 User I/O (135 PL, 13 PS MIO)
    • 4 GTX Transceivers

picozed

 

Z-Turn

Although similar in appearance to the MicroZed, the Z-Turn from MYIR differentiates itself with a few different features. A HDMI interface makes it interesting as a single board computer, while the onboard accelerometer could be useful for mobile applications or IoT devices.

 

  • Xilinx XC7Z010-1CLG400C (Zynq-7010) or XC7Z020-1CLG400C (Zynq-7020)
  • 1GB DDR3 SDRAM (2 x 512MB, 32-bit)
  • 16MB QSPI Flash
  • 1 x 10/100/1000M Ethernet
  • 1 x CAN
  • 1 x Mini USB2.0 OTG
  • 1 x USB-UART debug interface
  • 1 x HDMI (supports 1080p resolution)
  • 90/106 user I/O (7010/7020)
  • USB power supply or DC 5V/2A
  • Onboard three-axis acceleration sensor and temperature sensor
  • 5 x LEDs (3 x User LEDs, 1 x Power indicator, 1 RGB LED)
  • 1 x Buzzer

myir-z-turn

 

TE0720

Maybe the smallest Zynq SoM on the market, the TE0720 from Trenz Electronic delivers a lot of features for your real-estate and would be great for especially rugged applications.

 

  • Xilinx Zynq Z020 SoC
  • ARM® dual-core Cortex™-A9
  • 10/100/1000 tri-speed Gigabit Ethernet transceiver (PHY), SGMII accessible on a board-to-board connector
  • USB 2.0 high speed ULPI transceiver
  • 32-bit-wide 1 Gbyte DDR3 SDRAM
  • 32 Mbyte SPI Flash memory (for configuration and operation)
  • 4 Gbyte e-NAND (up to 32 GByte)
  • 2 × 100-pin and 1 x 60-pin high-speed expansion connectors
  • 152 FPGA I/Os (75 LVDS pairs possible) and 14 MIOs available on board-to-board connectors

 

TE0720

 

Mars ZX3

A really innovative concept from Enclustra, designed into a SODIMM form factor, the Mars ZX3 offers 108 I/Os in a small but mainstream package.

 

  • Xilinx Zynq-7020 AP SoC in the CLG484 package (XC7Z020)
  • ARM® dual-core Cortex™-A9
  • Xilinx Artix™-7 28 nm FPGA fabric
  • SO-DIMM form factor (67.6 x 30 mm, 200 pins)
  • 108 user I/Os
    • ARM peripherals (SPI, SDIO, CAN, I2C, UART)
    • FPGA I/Os (single-ended, differential or analog)
  • Gigabit Ethernet and USB 2.0 OTG PHYs
  • Up to 1 GB DDR3 SDRAM
  • 512 MB NAND flash
  • 16 MB quad SPI flash
  • Single 3.3 V supply voltage

mars_zx3_1000

 

Zynq MMP

The only Zynq SoM on the market that carries the largest in the Zynq-7000 family, the Zynq MMP from Avnet is loaded with either the XC7Z045-1FFG900 or the XC7Z100-2FFG900. The Zynq MMP targets applications that require a great amount of FPGA resources or up to 8 gigabit transceivers.

 

  • Dual ARM® Cortex™-A9 MPCore™
  • Up to 800 MHz operation
  • 1 GB DDR3 memory
  • 256 Mb Quad SPI Flash
  • 128MB parallel Flash (PL side)
  • Micro SD card cage
  • 4 GB micro SD Card Included
  • 10/100/1000 Ethernet
  • USB USB 2.0 port
  • USB UART
  • 8KB I2C EEPROM
  • 132 User I/O via module connectors
  • 8 GTX transceivers via module connectors

zynq-mmp

 

 

 


Sneak look at the new Robust Ethernet FMC

$
0
0

Here are the first images of my new product: the Robust Ethernet FMC.

This new variation of the Ethernet FMC contains all the features of the standard version but has been designed to fit the 10mm height profile of the Vita 57.1 standard. The Robust Ethernet FMC is perfect for the more rugged gigabit Ethernet applications, and here’s why:

  • 4 x 10mm stand-offs positioned to fit the mounting holes of the Vita 57.1 standard
  • Separated RJ45 and magnetics with filtering on every coil for greater isolation and protection
  • LEDs don’t cross the isolation barrier for maximum ESD protection

Contact me if you’d like more information on this product or others.

robust-ethernet-fmc-1

robust-ethernet-fmc-4Here is the Robust Ethernet FMC on the MicroZed FMC Carrier:

robust-ethernet-fmc-microzed-1 robust-ethernet-fmc-microzed-2

Using Chipscope and SDK at the same time

$
0
0

Today I was having problems debugging a design in Chipscope and SDK. For some reason, every time I used the Chipscope trigger (either the armed trigger or immediate) the Microblaze would reset or jump to another part of the code. I figured that Chipscope was messing with the stack pointer but I couldn’t find anything in the forums for such a problem. I finally came across a solution here:

[14.6] SDK and Chipscope do not work together

The solution didn’t put any light on why the problem occurs, but it did fix my problem – many thanks to moderator htsvn. Here’s my clean and illustrated version of the solution:

  1. Connect the power supply and programming cables to the board.
  2. Launch SDK.
  3. Program the FPGA using SDK: “Xilinx Tools->Program FPGA”.chipscope-sdk-problem4
  4. In the SDK, from the menu, select “Run->Debug As->Launch on Hardware (System Debugger)” as shown. Alternatively, you can use “Run As” if you don’t need to debug the code.chipscope-sdk-problem5
  5. Launch Chipscope Analyzer and select from the menu “JTAG Chain->Open plug-in”.chipscope-sdk-problem1
  6. Type in the following parameter and click OK:
    • xilinx_tcf URL =tcp::3121chipscope-sdk-problem2
  7. 
    

    This will detect the chain and you can see the devices on the chain.chipscope-sdk-problem3

  8. Import the CDC file using Chipscope Analyzer (or just open up a preconfigured Chipscope project file).
  9. Set the trigger points in Chipscope and click on Apply Settings and ARM trigger
  10. In the SDK Debug Perspective set the break-points in the C code and run through the code.

 

 

 

 

 

 

Back in black

$
0
0

Here’s a look at a batch of Ethernet FMCs fresh off the production line.

Ethernet FMC production batch

Ethernet gets robust

$
0
0

Announcing that the Robust Ethernet FMC is now in stock and available for purchase. Checkout the flashy new images of the first units, ravaging Ethernet packets in this tough new form factor.

KickStarter Campaign Launched: OnCourse Goggles

$
0
0

In recent weeks I’ve been working with some great people on an incredible new product for open water swimmers: OnCourse Goggles. Today we announced the launch of a KickStarter campaign which might help us to reach more people with this technology.

Check it out here: https://www.kickstarter.com/projects/oncoursegoggles/oncourse-goggles-navigate-open-water-and-swim-stra

Your support is greatly appreciated!

Here are some photos of the prototype electronics which I assembled in my lab. My soldering iron is in the background, but nothing on this board was actually hand soldered, it’s all QFNs, LGAs and 0402 passives. There’s no FPGA, just a micro and a bunch of very cool MEMS devices:

Viewing all 89 articles
Browse latest View live