cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

AXI Basics 5 - Create an AXI4-Lite Sniffer IP to use in Xilinx Vivado IP Integrator

Moderator
Moderator
3 2 2,668

Introduction

In some cases, it might be useful to sniff an AXI interface to analyze the transactions which are happening on it. In this article I will show you how to create a basic AXI4-Lite sniffer IP which will count the read/write transactions happening at a specific address.

We will start by writing the HDL (Verilog) code, then package the code as an IP and finally we will add this IP to an IP Integrator Block Design (BD).

The AXI Sniffer we will create will have an AXI4-Lite input interface to sniff an AXI4-Lite link and two outputs to give the number of Read and Write transactions which happened at a specific address (which will can configured through the GUI).

1.png

 


Create an AXI Sniffer IP to use in Vivado IP Integrator (tutorial)

 

  1. Download the design files attached to this article

  2. Open Vivado 2019.2

  3. In the Tcl console, cd into the unzipped directory (cd AXI_Basics_5)

  4. In the Tcl console, source the script tcl (source ./create_proj.tcl)

    This will create a Vivado project with a BD including an AXI VIP set as AXI4-Lite master and an AXI GPIO IP. This is very similar to the final design we made in the AXI Basics 3 article.
    2.png
    In this project, we will create the AXI Sniffer IP then try to connect it to the AXI4-Lite interface between the AXI VIP and the AXI GPIO IPs

    We can start by writing the HDL (Verilog) code for our AXI Sniffer IP

     

  5. Double-click on the AXI_Sniffer.v file in the Sources window to open the file in the text editor

    3.png

    We first need to declare the ports of the IP. We need an AXI4-Lite interface. As per the AMBA® AXI™ and ACE™ Protocol Specification available from the ARM website (link), these are the signals required on an AXI4-Lite interface

    4.png

    We also need to add the 2 ports (read_accesses and write_accesses) which will output the count of read/write accesses to the address the IP will be watching.

     

  6. Add the following code to declare all of the required signals.

    module AXI_Sniffer
    (
        input           aclk,
        input           aresetn,
        input           s_axi_arvalid,
        input           s_axi_arready,
        input [31:0]    s_axi_araddr,
        input [2:0]     s_axi_arprot,
        input           s_axi_rvalid,
        input           s_axi_rready,
        input [31:0]    s_axi_rdata,
        input [1:0]     s_axi_rresp,
        input           s_axi_awvalid,
        input           s_axi_awready,
        input [31:0]    s_axi_awaddr,
        input [2:0]     s_axi_awprot,
        input           s_axi_wvalid,
        input           s_axi_wready,
        input [31:0]    s_axi_wdata,
        input [3:0]     s_axi_wstrb,
        input           s_axi_bready,
        input           s_axi_bvalid,
        input [1:0]     s_axi_bresp,
        output [31:0]   read_accesses,
        output [31:0]   write_accesses
        );

     

    Note: All of the AXI4-Lite signals are set as input in this case because the IP should not act on the AXI4-Lite interface, only monitor the traffic on it


    Then, our IP needs to have a parameter to set the address which we want to monitor

  7. Add the following code to add the parameter for the monitoring address

    module AXI_Sniffer
    #(
        parameter  SLAVE_BASE_ADDR  = 32'h40000000
    )
    (

     

     

    Finally, we need to add the logic which will count the number of accesses to the address. The code increases a counter each time tready and tvalid are high while the address we are looking at is set.

  8. Add the following code to the file

    reg [31:0] read_accesses_cnt;
    reg [31:0] write_accesses_cnt;
         
    assign read_accesses  = read_accesses_cnt;
    assign write_accesses = write_accesses_cnt;
         
    //Check the Read Address Channel
    always @(posedge aclk)
    begin
        if(aresetn == 0)
        begin
            read_accesses_cnt  = 0;
        end
        else if (s_axi_arready && s_axi_arvalid && s_axi_araddr == SLAVE_BASE_ADDR)
        begin
            read_accesses_cnt = read_accesses_cnt + 1;
        end
        else
            read_accesses_cnt = read_accesses_cnt;
    end
         
    //Check the Write Address Channel
    always @(posedge aclk)
    begin
        if(aresetn == 0)
        begin
            write_accesses_cnt = 0;
        end
        else if (s_axi_awready && s_axi_awvalid && s_axi_awaddr == SLAVE_BASE_ADDR)
        begin
            write_accesses_cnt = write_accesses_cnt + 1;
        end
        else
            write_accesses_cnt = write_accesses_cnt;
    end
    
    endmodule

     
  9. Save the file AXI_Sniffer.v

    In IP Integrator, there is a feature which allow the user to import a HDL file into a BD that we can try.

  10. Right-click on the BD and click Add Module...


    5.png

     

    We can see that the tool correctly groups all of the s_axi_* signals to create an interface s_axi. However, if we try to connect this interface on the existing connection between the AXI VIP and the AXI GPIO, the tool will not allow us to.

    6.png

    This is because the import module tool has set the s_axi interface as a slave and Vivado only allow a master interface to be connected to a single slave.

    To create the monitor IP we need to package the code as an IP, which will give us more options for the interface.

  11. Click on Tools > Create and Package New IP...

  12. On the second page of Create and Package New IP, select Package a specified directory and click Next

  13. Select the directory AXI_Basics_5/src/hdl/AXI_Sniffer then click Next > Next (keep default settings) > Finish

    This will create an IP Packager project. In the Package IP tab, click on the Ports and Interface section.

    7.png

    We can see that the tool has again grouped the s_axi_* signals into a s_axi interface. But this interface is still set as a Slave. To be able to connect to an existing AXI bus, we need to tell the tool that this is a not a slave interface but a monitor interface.

     

  14. Right-click on the s_axi interface and click Edit Interface...


    8.png

     

  15. In the General tab of the Edit Interface window, change the Mode to monitor


    9.png

     

  16. Then click on the Port Mapping tab and enable Hide Mapped Port

    10.png

     

  17. For each IP's Physical Ports named s_axi_*, find the matching Interface's Logical Ports and click Map Ports


    11.png

     

  18. When all of the s_axi_* IPs ports are mapped click OK to close the Edit Interface window

  19. Right-click again on the s_axi interface and click Associate Clocks...


    12.png

     

  20. In the next window, aclk should be automatically selected. Click OK

    13.png

     

  21. Click on the Review and Package section and click Package IP.

    14.png

     

    This will close the IP Packager project.

  22. Remove the previous AXI_Sniffer IP from the BD of the initial project

  23. Right-click on the BD of the initial project and click add IP. Find the AXI Sniffer IP (which should have been automatically added to the IP catalog) and add it to the BD


    15.png

  24. Try to connect the s_axi interface of our new AXI Sniffer IP to the bus between the AXI VIP and the AXI GPIO. This is now possible


    16.png
  25. Connect the aclk and aresetn input port of the custom IP to the corresponding BD ports

  26. Validate the BD design. You should get no errors or critical warnings. Save the BD.

    Finally, we can verify that our IP is working in simulation.

  27. Launch the simulation and add the port read_accesses and write_accesses of the AXI_Sniffer IP to the waveform window


    17.png

     

  28. Restart the simulation and run it for 3us

    18.png

    We can see in the simulation waveform that two write and two read transactions are happening. However our IP is counting only two write transactions and one read transaction

    19.png

    We can have a look at the addresses for each transaction to see if the output is correct. The two write transactions are happening at address 0x4000_0000 which is the address watched by the IP

    20.png

    However, only one read transaction is targeting the address 0x4000_0000 (the other reads 0x4000_0008) so the behavior of our IP is correct

    21.png

    This article shows only one example of what can be done with an AXI Sniffer (or monitor) IP. You can edit the Verilog code to add your own features.

     

     

     

     

Tags (1)
2 Comments
Scholar
Scholar

@florentw,

Thank you!  I was wondering how I'd go about doing this, and the tutorial is quite helpful.

Dan

Moderator
Moderator

@dgisselq 

Glad to know that this is helpful.