This tutorial is meant for Verilog programmers who want to use the Xilinx ZYNQ 7000 to stream through an AXI Slave Interface.
- PYNQ 2.6 image
- TUL-2 Board
- Vivado 2021.1
In this case I took verilog from the AXI Peripherals and edited it to build a simple counting interface. There are three modules:
- TopLevelModule
- SlaveStream which takes in an AXI stream and accumulates the streamed in data.
- RegisterFile which interfaces to the CPU to return summed results. The only changes here were a capture of the total Value and output of control Register.
There are Verilator scripts for my own testing purposes.
The simplest way to package the IP through the gui is:
- git clone http://github.com/rogerpease/AXISlaveStreamTutorial
- cd AXISlaveStreamTutorial
- Start Vivado and Create a new project. Call it whatever you want and you can ignore the steps about adding IP/selecting parts/boards.
- Tools->Create and Package New IP and select "Package a Specific Directory". Click Next.
- Select the AXISlaveStreamTutorial directory and Click Next.
- Enter a project name and click next.
- It should figure out the AXI interfaces and the hierarchy. All you should need to do is:
These steps are captured for automation in the RunPackageIP.py script.
- Start Vivado and Create a new RTL project (I call mine FPGAImageProject).
- You don't need to add RTL source but be sure to select your board from the board/part menu.
- Click "Project Manager"->"Settings"->"IP" and add your IP directory from the prior step as a IP Repository. It should find the IP even in a subdirectory.
- Click "Create Block Design" and make a new Block design.
- Add the AXISlaveStreamTutorial directory as an IP Repository. It should find one directory.
- Add the following:
- ZYNQ 7000
- "AXI Direct Memory Access"
- AXISlaveStreamTutorialIP
- Run "Run Block Automation" (should be an option in a ribbon at the top of the Block Diagram).
- Double-Click on the ZYNQ 7000:
- Select "PS-PL Configuration"->"HP Slave AXI Interface"->"S AXI HP0 interface" to include a Slave High Performance Port.
- If you select "Run Block Automation" you may need to reselect this.
- Select "PS-PL Configuration"->"HP Slave AXI Interface"->"S AXI HP0 interface" to include a Slave High Performance Port.
- Double-Click on the AXI Direct Memory Access Peripheral to:
- Remove the Write Channel
- Turn off Scatter-Gather
- Run "Run Connection Automation" and select "All Automation".
- Make sure:
- The AXI Direct Memory Access M_AXIS_MM2S connects to the AXISlaveStreamTutorial IP slavestream interface. This is what writes the stream data.
- The AXI Slave Tutorial IP has all its resets and clocks connected. They can be connected to the other resets/clocks (respectively).
- The AXI Interconnect axi_mem_interconn:
- axi_dma_0/M_AXI_M2SS ties to axi_mem_interconn/S00_AXI
- axi_mem_interconn/M00_AXI ties to the processing system/S_AXI_HP0. 1. This is how the DMA fetches processor memory to feed to the stream interface. If the S_AXI_HP0 interface is missing you missed the "S AXI HP0 interface" option or it was undone by the Block Automation.
- The AXI Interconnect ps7_0_axi_periph:
1. There should be connections to both peripherals.
- This is how the CPU communicates with the peripherals (to configure/read registers/etc).
- Go to the "FPGA Image" sources area, right-click and select "Generate HDL Wrapper". The tool that makes the netlists can't read a Block Diagram.
- Run "Generate Bitstream" and wait for the bitstream to generate. This may take 5 minutes or so.
You should find a bit file and hwh file in your directory (you may need to do a find for files ending in those extensions).
These steps are captured for automation in the RunMakeImage.py script.
I normally upload to /home/xilinx/AXISlaveStreamTutorial
There is a SendStream.py script which will:
- Stream in numbers to the streaming interface. BE SURE TO RUN THE SCRIPT AS ROOT
- Those numbers are summed together and the result is placed in the Register File.
- The total is read back the sum through the register file.
The copy steps are captured for automation in the PushFiles.py script. Be sure to update the IP address of your board.