How to Receive Read Data - 1.1 English

AXI Verification IP LogiCORE IP Product Guide (PG267)

Document ID
PG267
Release Date
2024-06-07
Version
1.1 English

There are two techniques for obtaining the read data:

  • Receiving it through the read driver of the master agent (see the driver_rd_data_method_one and driver_rd_data_method_two in the *mst_stimulus.sv file).
  • Obtaining it through the monitor of the VIP (see the monitor_rd_data_method_one and monitor_rd_data_method_two in the *exdes_generic.sv file).
To receive data from the monitor, follow these steps:
  1. Obtain the monitor transaction from the item_collected_port. In this example, it comes from the master agent.
  2. If the cmd type is XIL_AXI_READ in the monitor transaction, use the get_data_beat and get_data_block to obtain the read data.
If the cmd type is XIL_AXI_WRITE in the monitor transaction, use the get_data_beat and get_data_block to obtain the write data. The monitor_rd_data_method_one shows how to receive the data beat through the monitor transaction. The monitor_rd_data_method_two shows how to receive the data block through the monitor transaction.
To receive data from the read driver, follow theses steps:
  1. Use the read driver in the master agent to create a read transaction handle.
  2. Randomize the read transaction. If you want to generate a specific read command, use the APIs in the axi_transaction class to set the address, burst length, and so on or randomize the transaction with specific values.
  3. Set the driver_return_item_policy of the read transaction to be any of the following values: XIL_AXI_PAYLOAD_RETURN or XIL_AXI_CMD_PAYLOAD_RETURN
  4. Use the read driver to send read transaction out.
  5. Use the read driver to wait for the response.
  6. Use the get_data_beat/get_data_block to inspect data from the response transaction. The driver_rd_data_method_one shows how to obtain a data beat from the read driver. The driver_rd_data_method_two shows how to obtain a data block from the read driver.
Note: The API get_data_beat:get_data_beat returns the value of the specified beat. It always returns 1024 bits. It aligns the significant bytes to the lower bytes and sets the unused bytes to zeros.

The is not always the RDATA representation. If the data width is 32 bits and the transaction is subsize burst (1B in this example), only the last byte of get_data_beat is valid. This is different from the Physical Bus.

 get_data_bit             Physical Bus
   1024  ...      0         32        0
   ----------------         -----------
   |             X| 	    |        X| 
   |             X| 	    |      X  |
   |             X| 	|    X    |
   |             X|         | X       |
   ----------------         -----------
Note: The API get_data_block: get_data_block returns 4K bytes of the payload for the transaction. This is not always the RDATA representation. If the data width is 32 bits and the transaction is subsize burst (1B in this example), it aligns the significant bytes to the lower bytes and set the unused bytes to zeros.
	get_data_block          Physical Bus
     32    ...      0         32        0
   0 ----------------         -----------
     | D   C   B   A| 	    |        A|
     | 0   0   0   0| 	|      B  |
     | 0   0   0   0| 	    |    C    |
     | 0   0   0   0| 	    | D       |
     | 0   0   0   0|        -----------
     | 0   0   0   0|         
  1k----------------         
  
  
  task monitor_rd_data_method_one(input axi_monitor_transaction updated);
    xil_axi_data_beat                       mtestDataBeat[];
    mtestDataBeat = new[updated.get_len()+1];
   for( xil_axi_uint beat=0; beat<updated.get_len()+1; beat++) begin
      mtestDataBeat[beat] = updated.get_data_beat(beat);
    //  $display(" Read data from Monitor: beat index %d, Data beat %h", beat, mtestDataBeat[beat]);
    end  
  endtask

  task monitor_rd_data_method_two(input axi_monitor_transaction updated);
    bit[8*4096-1:0]                         data_block;
    data_block = updated.get_data_block();
  	 	// $display(" Read data from Monitor: Block Data %h ", data_block);
  endtask 
      
    task driver_rd_data_method_one();  
    axi_transaction                         rd_transaction;
    xil_axi_data_beat                       mtestDataBeat[];
    rd_transaction = agent.rd_driver.create_transaction("read transaction with randomization");
    RD_TRANSACTION_FAIL_1a:assert(rd_transaction.randomize());
    rd_transaction.set_driver_return_item_policy(XIL_AXI_PAYLOAD_RETURN);
    agent.rd_driver.send(rd_transaction);
    agent.rd_driver.wait_rsp(rd_transaction);
    mtestDataBeat = new[rd_transaction.get_len()+1];
    for( xil_axi_uint beat=0; beat<rd_transaction.get_len()+1; beat++) begin
      mtestDataBeat[beat] = rd_transaction.get_data_beat(beat);
   //   $display("Read data from Driver: beat index %d, Data beat %h ", beat, mtestDataBeat[beat]);
    end  
  endtask 

  
  task driver_rd_data_method_two();  
    axi_transaction                         rd_transaction;
    bit[8*4096-1:0]                         data_block;
    rd_transaction = agent.rd_driver.create_transaction("read transaction with 
	 	 randomization");
    RD_TRANSACTION_FAIL_1a:assert(rd_transaction.randomize());
    rd_transaction.set_driver_return_item_policy(XIL_AXI_PAYLOAD_RETURN);
    agent.rd_driver.send(rd_transaction);
    agent.rd_driver.wait_rsp(rd_transaction);
    data_block = rd_transaction.get_data_block();
   // $display("Read data from Driver: Block Data %h ", data_block);
  endtask 

For more information, see the simset sim_adv_mst_active_* in the Vivado example design.