Creating a Custom AXI IP block in Vivado

Author: Farid M, https://embeddeddesign.org/

In this tutorial, I will show you how to add a custom AXI IP block and transfer data from the Processing System to the Programming Logic on AXI4 Data Bus in Xilinix Vivado tool development, using Zedboard development board.

I will create a simple adder in VHDL that will add two numbers. The user will enter two values to sum on the PS, as  inputs to the PL, and the PL will sum up these values. The will display the sum on Tera Term. All the data transfer takes place on AXI4 peripheral.

More information about AXI4 protocol can be found at this link: AXI Reference Guide

Zedboard

Figure1. Zedboard Development board

Create a new Vivado Project

In this demo, I am using Vivado 16.4. Next, I will show how to start creating the Adder custom IP.

Open Vivado from the start menu and create a new project, and save it in your working directory. I named this project AXI4_Demo. Then hit next and select RTL Project, next select Zedboard Zynq as your target hardware. Then, the project window will open up after you hit finish.

Create Block Design

Under IP Integrator, select Create Block design, and name it. Click Add IP and search for ZYNQ7 Processing System, once you make the selection the block diagram will show up as in the figure below:Image1

Figure2. ZYNQ7 Processing System

Create Adder VHDL Code

Next, we need to create the VHDL logic for the adder we need to interface with the PS via AXI4 peripheral.

Create a sub-folder in the Vivado project folder, and name it VHDL. Then copy this code shown below into a text editor and save as it as a Adder.vhd under the VHDL sub-folder you created.

------------------------------------------------------------
-- Engineer: F.Mabrouk
------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Adder_Unsigned is
port (
FirstValue : in std_logic_vector(30 downto 0);
SecondValue : in std_logic_vector(30 downto 0);
Sum : out std_logic_vector(31 downto 0)
);
end Adder_Unsigned;

architecture rtl of Adder_Unsigned is

begin

Sum <= std_logic_vector(resize(unsigned(FirstValue),32)+resize(unsigned(SecondValue),32));

end rtl;

Create Adder IP

On the Tools menu, select Create and Package New IP, hit next and select Create a New AXI4 Peripheral, hit next and name the IP. I named it: AdderDemoIP, hit next and keep everything as shown below:

Image2Figure3. AXI4 configuration

Here we have selected 4 registers of 32 bit data width. Then, hit next and select Edit IP, and click Finish. A new window will open up, where will will edit the newly created IP .

Now we need to add the VHDL file we wrote to the newly created IP. From the project menu select Add Sources, and hit next and then select Add Files. Then add the Adder.vhd file you saved. Then go to AdderDemoIP_v1_0_S00_AXI_inst file and do the following changes:

Add this piece of code just above begin (line120):

signal SUMSig : std_logic_vector(31 downto 0); 
component Adder_Unsigned 
port ( 
FirstValue : in std_logic_VECTOR(30 downto 0); 
SecondValue : in std_logic_VECTOR(30 downto 0); 
Sum : out std_logic_VECTOR(31 downto 0)); 
end component;

At line 390 add this:

 -- Add user logic here
Adder_0 : Adder_Unsigned 
port map ( 
FirstValue=> slv_reg0(30 downto 0), 
SecondValue => slv_reg1(30 downto 0), 
Sum=> SumSig); 
-- User logic ends

Al line 363 change that line of code into this:

 reg_data_out <= SumSig;

At line 352 do the following change:

 process(slv_reg0,slv_reg1, SumSig, slv_reg3, axi_araddr, S_AXI_ARESETN, slv_reg_rden)

When you are done, hit save and you will see that the files hierarchy changed, and it looks as below:

Image3

Figure4. Adder IP files Hierarchy

Now, click on Package IP and hit File Groups then click on Merge Changes from File Groups. Then click on Review and Package and click on Re-Package IP, then hit close so that the newly created window for IP configuration is closed.

Now, on the main project window, where the PS diagram is shown, click and Add IP and look for: AdderDemoIP. Once you find it, double click on it so that it is added to the project. Click on Run Block Automation and then click on Run Connection Automation.Then click on Regenerate Layout. When your done click on Validate Design to make sure there is no errors. Then save it. Your system block diagrams will look as below:

Image4

Figure5. System block diagram

Under Block Designs, right hand click on design_1 and select Create HDL Wrapper. Then again right hand click on design_1 and select Generate Output Products, then select Out of Context per IP, and hit Generate. When this process is done, hit Ok. Then from the Flow Navigator on the main menu on the left select Generate Bit Stream.

SDK Project

Once the bit stream is generated, go File on the left top corner and click on Export, then Export Hardware, and select Include Bitstream, then hit Ok. Then, right hand click on File again and hit Launch SDK. The SDK project will open up automatically and it should look as below:

Image5Figure6. SDK Project Window

Click on File on top left corner and select New and then select Application Project. Name the project: Adder, then click next and select Hello World and hit Finish.

Now if you look under Adder in the Project Explorer to the left you will see a folder named src. If you click on scrc you will a file named: helloworld.c. Right hand click on this file and select rename and name it: Adder.c.

Now open the file Adder.c, and delete its content, and paste the following source code instead, and then build the project.

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

Xuint32 *baseaddr_p =XPAR_ADDERDEMOIP_0_S00_AXI_BASEADDR;

int main()
{
init_platform();

xil_printf("AXI4 Adder IP Demo\n\r");

*(baseaddr_p+0) = 77;
*(baseaddr_p+1) = 23;
while(1)
{
	// Register 0
	xil_printf("First Value: %d \n\r", *(baseaddr_p+0));

	// Register 1
	xil_printf("Second Value: %d \n\r", *(baseaddr_p+1));

	//Register 2
	xil_printf("Sum of first and second values is: %d \n\r", *(baseaddr_p+2));

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

	sleep(1);

	*(baseaddr_p+0)=*(baseaddr_p+0)+1;
	*(baseaddr_p+1)=*(baseaddr_p+1)+1;
}

return 0;
}

Zedboard Connection to Serial Ports

Connect the Zedboard as in the image blow: Verify that the two serial ports ( top left corner of the picture ) are connected to your PC: one serial port is used for programming the FPGA and other serial port is used for communication with Tera term. Also make sure the the power switch is ON. A green LED will be on when the board is powered up.

Zedboard2Figure7. Zedboard Serial Port Communication Connections

Serial Port Configuration

Open Tera Term and select connection to USB serial port, then set the correct baud rate by going to Setup and then selecting Serial Port. Set the baud rate to 115200 bps. Click again on Setup and select Terminal, then check Local Echo and change New-line receive and Transmit to: LF and then hit Ok. Below are images of the serial port and terminal setup:

tera TermFigure8. Tera Term Configuration

Programming the FPGA

After you have built the project with no errors, click on Xilinx Tools on top menu and select Program FPGA. When it is programmed a blue LED will turns ON. Then, click on Run As ( by right hand clicking on project name) and select Launch on Hardware. Then you will see the following display on Tera Term. This display concludes this tutorial and it proves that sum of any two values is correct, and that the AXI4 data transfer is working as it should

Image6

Figure9: Adder Custom IP Test Results

Conclusion

A custom adder IP has been added where AXI4 communication interface between PS and PL has been implemented. In the next tutorial, I will show you how to use AXI4 to control GPIOs/LEDs on the Zedboard development kit.

Author: Farid M, https://embeddeddesign.org/

If you find any of the projects posted here helpful to you while working on similar projects, or you learned something from any of the topics discussed, please do not hesitate to make a donation, whatever amount you can afford, just as a gesture of appreciation and to keep this website alive and progressing so that its benefits extends to many younger engineers and students around the globe.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.