Updated: Nov 12
Last week we examined the AXI VIP (verification IP), which we use when working with memory-mapped AXI or AXI-Lite. This week, we will examine the AXI Stream VIP, which is similar in behaviour but has enough key differences to warrant a separate blog.
The AXI Stream VIP is extremely useful when we want to generate signal and image processing IP that use AXI Stream for interfacing. Using the AXI VIP, we can generate stimulus data and of course act as a slave to ensure data is output from the UUT.
Compared to the AXI VIP previously examined, the AXI Stream VIP is much simpler to get up and running, although it does use the same two elements in the static and dynamic environments. Again, the static element is what we create in Vivado, and the dynamic is what we implement and control in the test bench.
The AXI Stream VIP can be configured as master, slave, or pass through where we can check the AXI protocol if we want.
The configuration for each of the AXI Stream VIPs is performed in Vivado as can be seen below.
For this tutorial, we will be implementing two VIP modules that act as AXI Stream master and slave. We will be placing an AXI Data FIFO between them. This will allow the creation of a simple example which in turn will allow the creation of a test bench that shows how we can use the AXI Stream VIP to write into a stream and read from a stream.
Just like with the previous example, we need to ensure we are working with a Verilog design when we create the HDL wrappers.
When prompted, let Vivado manage the wrapper and auto update any changes which take place in our design.
Once we have created the design we want to test, we are ready to create two new files for the test bench.
tb_axis.sv – This is a system Verilog header file which contains most of our test bench using the AXIS VIP
tb_top.sv – This is a system Verilog file which contains the structural elements of the test bench
Within the SystemVerilog header file, we need to first declare the three packages created by Vivado to work with the AXI Stream VIP. There is one package for over AXI Stream VIP, along with a package each for each of the VIP instantiations.
The next step is to declare the AXI Stream VIP as either a master or slave using the appropriate agent.
Once the agent has been declared, we can create new agents and start them.
mst_agent = new("master vip agent",DUT.design_1_i.axi4stream_vip_0.inst.IF);
slv_agent = new("slave vip agent",DUT.design_1_i.axi4stream_vip_1.inst.IF);
The test bench itself is pretty simple. We are going to write in a byte into the FIFO and then read it out. This will demonstrate the AXI Stream VIP for both read and write operations in our test bench.
Starting with the write first, the first step is to create a write transaction from the master agent. We can then set the data for the AXI Stream. Since this example has no side band signals, we are the able to send the write.
mtestWData = 8'h55;
wr_transaction = mst_agent.driver.create_transaction("write transaction");
Of course, we need to be able to generate a ready signal to read from the FIFO. This will cause the ready signal to pulse on and off allowing read out of the FIFO.
ready_gen = slv_agent.driver.create_ready("ready_gen");
Finally, the tb_top.sv file maps in the device under test and called the test function from the SV header file.
When this is simulated, we can see the write from the master AXI Stream VIP to the FIFO and the read from FIFO performed by the slave AXI Stream VIP.
This is a simple application, however, we are able to see how we can create read and write transactions easily for testing an AXI Stream IP.
I have uploaded the project to my GitHub.