...
...

Simulating AXI BFM Examples Available in Xilinx CORE Generator

The ISE CORE Generator is a design entry tool which generates parameterized cores optimized for Xilinx FPGAs:

  1. Architecture-specific, domain-specific (embedded, connectivity and DSP), and market specific IP (Automotive, Consumer, Mil/Aero, Communications, Broadcast etc.)

  2. User-customizable IP functions range in complexity from commonly used functions, such as memories and FIFOs, to system-level building blocks, such as filters and transforms

  3. Detailed information on each core (data sheets, user guides, release notes, licensing)

The AXI BFM IP comes together with examples and test benches that demonstrate the abilities of AXI3, AXI4, AXI4-Lite, and AXI4-Stream Master/Slave BFM pair. These examples can be used as a starting point to create tests for custom RTL design with AXI3, AXI4, AXI4-Lite and AXI4-Stream interface. The examples can be accessed from CORE Generator, IP Catalog—View by Function—AXI Infrastructure—AXI Bus Functional Model (Figure 1).

Figure 1. AXI BFM Examples in CORE Generator

The examples and test benches can be obtained by generating the AXI BFM IP available in the “AXI Infrastructure” or “Debug & Verification” folder of the CORE Generator IP catalog. When generated, the AXI BFM IP delivers the user-specified <component_name> directory. The directory includes a README.txt file that describes how to set up the simulation environment and run the examples (vendor-specific scripts, such as simulate_aldec, are available in the simulation/functional subfolder).

See Simulating AXI-Based Designs in Active-HDL or Simulating AXI-Based Designs in Riviera-PRO for details on how to run the AXI BFM simulation.

Let’s look at the first example available with the package, the AXI3 BFM example test bench and tests. As all the other examples from this package, this one has the AXI master is connected to a single AXI slave (Figure 2) to give a visibility into both master and slave sides of the code.

Figure 2. Example Test Bench and Test Case Structure

The example test (cdn_axi3_example_test.v) contains the master and slave code and uses direct tests to transfer data between the master and slave and simulate different scenarios such as simple, looped, and parallel write and read burst transfers. Figure 3 illustrates this example design hierarchy as it appears in Riviera-PRO 2011.10 (note that master_0 and slave_0 units have a lock sign since they are encrypted).

Figure 3. Example Test Hierarchy To illustrate the basic testing concepts, let’s look into a simple looped write and read burst transfer scenario. The following code snippet shows parameter declaration used to configure the actual AXI BFMs instantiated under the tb():

//------------------------------------------------------------------------
// Module "test", AXI BFM Configuration - tb()
//------------------------------------------------------------------------
parameter MASTER_NAME = "MASTER_0";
parameter SLAVE_NAME = "SLAVE_0";
parameter DATA_BUS_WIDTH = 32;
/* ... Other parameters ... */

// Create an instance of the example tb
cdn_axi3_example_tb #( MASTER_NAME,
                       SLAVE_NAME,
                       DATA_BUS_WIDTH,
                       /* ... Other Parameters ... */)
                     tb();

//------------------------------------------------------------------------
// Module "cdn_axi3_example_tb", Actual AXI BFM Instantiation
//------------------------------------------------------------------------
cdn_axi3_slave_bfm #( SLAVE_NAME,
                      DATA_BUS_WIDTH,
                      ADDRESS_BUS_WIDTH,
                      /* ... Other Parameters ... */)
                      slave_0 (/* ... Actual Ports ... */);

And the following master code does 3 sequential writes and reads in a for loop. The WRITE_BURST and READ_BURST are standard AXI BFM channel level API tasks (defined in AXI Bus Functional Model User Guide), and the rest are just service tasks performing routine checks.

for (i = 0; i < 3; i = i + 1 ) begin
   // Full write transaction composed of multiple tasks:
   //    - SEND_WRITE_ADDRESS, SEND_WRITE_BURST
   //    - RECEIVE_WRITE_RESPONSE
   tb.master_0.WRITE_BURST( ..., test_data[i], ... );

   // Service task checks if the return response is equal to OKAY
   tb.CHECK_RESPONSE_OKAY ( response );

   // Full read transaction composed of SEND_READ_ADDRESS and RECEIVE_READ_BURST tasks
   tb.master_0.READ_BURST ( ..., rd_data, ... );

   // Service task checks if response vector from READ_BURST is equal to OKAY (the vector
   //     is created by concatenating all slave read responses together)
   tb.CHECK_RESPONSE_VECTOR_OKAY( vresponse, mtestBurstLength );

   // Service task checks if the received data is equal to sent data
   tb.COMPARE_DATA( test_data[i], rd_data );
end

Note that user control of the AXI BFMs is performed by making function calls to a specific AXI BFM core instance, using its hierarchical name. For example, the WRITE_BURST command initiates a write burst transaction with the tb.master_0 AXI Master BFM – stimulates the core to perform the write burst with the address, data, and other arguments.