cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Visitor
Visitor
1,924 Views
Registered: ‎05-07-2018

How to delay s_axi_rvalid in axi_vip slave?

Jump to solution

I'm using AXI Verification IP v1.1 from Vivado Design Suite.

I need to know how to insert random delays on rvalid.  Currently, the axi_vip slave sends data as fast as possible with no delay between beats.  I'd like it to delay the first beat, and subsequent data beats up to 32 clock cycles.  This is to simulate a relatively slow I/O device.  

 

    axi_ready_gen   can be used for WREADY, AWREADY, and ARREADY

 

What is used for RVALID?

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Xilinx Employee
Xilinx Employee
1,662 Views
Registered: ‎10-04-2016

Hi @giantpeach,

It wasn't clear that you were asking about the memory model. The AXI Slave with the memory model provides a different API to configure the delay between read data beats.

 

The function to set the desired policy is set_inter_beat_gap_policy. The two options are XIL_AXI_MEMORY_DELAY_FIXED and XIL_AXI_MEMORY_DELAY_RANDOM. The default policy is random.

 

The function to set the range for the random policy is set_inter_beat_gap_range. The default sets the min and max to 0, so there isn't a delay between read data beats.

 

If you used the fixed policy, you would use set_inter_beat_gap to set the delay between data beats.

 

I tried this out with the AXI VIP example design in 2018.2 and set my inter beat range for 0 to 10 clocks. Here's what the code looked like in axi_vip_0_mem_basic_stimulus.sv :

 

module axi_vip_0_mem_basic_stimulus(
  );
 

  ex_sim_axi_vip_slv_0_slv_mem_t                          agent;

  initial begin
    agent = new("slave vip mem agent",DUT.ex_design.axi_vip_slv.inst.IF); // agent is newed
    agent.mem_model.set_inter_beat_gap_delay_policy(XIL_AXI_MEMORY_DELAY_RANDOM);
    agent.mem_model.set_inter_beat_gap_range(0,10);
    agent.start_slave();                                                  //  agent starts to run

  end

endmodule

 

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------

View solution in original post

0 Kudos
8 Replies
Highlighted
Scholar
Scholar
1,892 Views
Registered: ‎08-07-2014

@giantpeach,

 

I need to know how to insert random delays on rvalid.  Currently, the axi_vip slave sends data as fast as possible with no delay between beats.  I'd like it to delay the first beat, and subsequent data beats up to 32 clock cycles.  This is to simulate a relatively slow I/O device.  

 

I am afraid that in this case you need to either modify the state machine within the slave VIP else write your own slave model to get such a behaviour.

 

------------FPGA enthusiast------------
Consider giving "Kudos" if you like my answer. Please mark my post "Accept as solution" if my answer has solved your problem

Highlighted
Visitor
Visitor
1,825 Views
Registered: ‎05-07-2018

 

@dpaul24 wrote:

 

 

I am afraid that in this case you need to either modify the state machine within the slave VIP else write your own slave model to get such a behaviour.

 


Hi dpaul24,

  Xilinx AEs recommend against modifying the VIP code.  If this feature can not be added, a different VIP is the only solution.

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
1,787 Views
Registered: ‎10-04-2016

Hi @giantpeach and @dpaul24,

The AXI VIP includes a function set_beat_delay that you can use to insert delay between the data beats in an AXI transaction.

 

There's example code in the API document that shows how to do this under the get_rd_reactive function. It would be best to look at the whole example, but I have included the relevant example functions here.

 

  task rd_response();
    axi_transaction                   rd_reactive;  //Declare a handle for read response
    forever begin
      agent.rd_driver.get_rd_reactive(rd_reactive); //Block till read transaction occurs
      fill_rd_reactive(rd_reactive);                //User fill in read response
      fill_beat_delay(rd_reactive);
      agent.rd_driver.send(rd_reactive);            //Write driver send response to VIP interface
    end 
  endtask

 

  // Fill beat delay into transaction
  function automatic void fill_beat_delay(inout axi_transaction t);
    integer unsigned        current_addr;
    xil_axi_uint            beat_delay[];
    xil_axi_uint            delay;
   
    current_addr = t.get_addr();
    beat_delay = new[(1<<t.get_size())];
    for (int beat_cnt = 0; beat_cnt <= t.get_len(); beat_cnt++) begin
      delay = {$urandom_range(0,10)};
      t.set_beat_delay(beat_cnt,delay);
    end
  endfunction: fill_beat_delay

 

You can download the AXI VIP API documentation here:

https://www.xilinx.com/products/intellectual-property/axi-vip.html#documentation

 

You want the associated file xilinx-vip-api-2018-1.zip.

 

Regards,

 

Deanna

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
Highlighted
Visitor
Visitor
1,741 Views
Registered: ‎05-07-2018

The example code is not in the API document.  It is, however in the installation directory:

...   /vivado2017.4/Vivado/2017.4/data/ip/xilinx/axi_vip_v1_0/ttcl/

 

This does not work for VIP slaves that have the built in memory.

 

Here’s what I did:

  task axi_vip_CPU0_rd_response();

    axi_transaction                   rd_reactive;  //Declare a handle for read response

    forever begin

      axi_vip_core0.rd_driver.get_rd_reactive(rd_reactive); //Block till read transaction occurs

      fill_rd_reactive_mem(rd_reactive, 32, 0);                //User fill in read response with data from backdoor read

 

      rd_reactive.addr_delay = $urandom_range(32, 0);

      rd_reactive.data_insertion_delay = $urandom_range(32, 0);

      rd_reactive.response_delay = $urandom_range(32, 0);

      foreach (rd_reactive.beat_delay[index] ) begin

        rd_reactive.beat_delay[index] = $urandom_range(32, 0);

        rd_reactive.set_beat_delay(index, rd_reactive.beat_delay[index]);

      end

 

      axi_vip_core0.rd_driver.send(rd_reactive);            //Read driver send response to VIP interface

    end 

  endtask

 

For function “fill_rd_reactive” (renamed fill_rd_reactive_mem in my test bench) , I have to get the data from backdoor read like this:

   function automatic void fill_rd_reactive_mem(var axi_transaction t, int ruser_width, bit cpu);

...

      for (int byte_cnt = 0; byte_cnt < number_bytes ; byte_cnt++) begin

       beat[byte_cnt] = axi_vip_core0.mem_model.backdoor_memory_read(current_addr);

 

        //increment current_addr

        current_addr += 1;

 

Unfortunately the VIP complains about something that does not occur on the waveform:

 

# ** Fatal: AXI4_ERRS_RDATA_STABLE: RDATA must remain stable when RVALID is asserted and RREADY low. Spec: section A3.2.1.

#    Time: 1760 ns Started: 1760 ns  Scope: tb_top.fp_checker_sim_bd_wrapper.fp_checker_sim_bd_i.axi_vip_core0.inst.IF.PC.arm_amba4_pc_msg_err File: /netapps/xilinx/vivado2017.4/Vivado/2017.4/data/xilinx_vip/hdl/axi_vip_axi4pc.sv Line: 726

 

As you can see in the attached bmp file, RDATA is not changing.  Even if it did, it would be ok because RREADY is high.

rdata_steady.bmp
0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
1,663 Views
Registered: ‎10-04-2016

Hi @giantpeach,

It wasn't clear that you were asking about the memory model. The AXI Slave with the memory model provides a different API to configure the delay between read data beats.

 

The function to set the desired policy is set_inter_beat_gap_policy. The two options are XIL_AXI_MEMORY_DELAY_FIXED and XIL_AXI_MEMORY_DELAY_RANDOM. The default policy is random.

 

The function to set the range for the random policy is set_inter_beat_gap_range. The default sets the min and max to 0, so there isn't a delay between read data beats.

 

If you used the fixed policy, you would use set_inter_beat_gap to set the delay between data beats.

 

I tried this out with the AXI VIP example design in 2018.2 and set my inter beat range for 0 to 10 clocks. Here's what the code looked like in axi_vip_0_mem_basic_stimulus.sv :

 

module axi_vip_0_mem_basic_stimulus(
  );
 

  ex_sim_axi_vip_slv_0_slv_mem_t                          agent;

  initial begin
    agent = new("slave vip mem agent",DUT.ex_design.axi_vip_slv.inst.IF); // agent is newed
    agent.mem_model.set_inter_beat_gap_delay_policy(XIL_AXI_MEMORY_DELAY_RANDOM);
    agent.mem_model.set_inter_beat_gap_range(0,10);
    agent.start_slave();                                                  //  agent starts to run

  end

endmodule

 

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------

View solution in original post

0 Kudos
Highlighted
Visitor
Visitor
1,654 Views
Registered: ‎05-07-2018

Hi Deanna,

  We are getting closer to a solution.

Something is wrong with the randomization. I ran 4 different seeds using my_agent".mem_model.set_inter_beat_gap_range(0,10);"

Two runs had delays of only one clock.  One had a single delay of 2 clocks with a few 1 clock delays.  The last had a single delay of 3 clocks with a few 1 clock delays.

What I need is set_inter_beat_gap_range(0,31), but a run with that had delays of only one clock cycle.

 

I'll kick off a few thousand runs and see if coverage shows some larger delays.

 

rvalid_delay.bmp
0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
1,642 Views
Registered: ‎10-04-2016

Hi @giantpeach,

Which simulator are you using? Are you still using 2017.4?

 

The AXI VIP code for generating the interbeat gap is pretty generic; the function to look at is get_inter_beat_gap in axi_vip_pkg.sv. Here's how it uses the range that you provided: 

 

rnd = ($urandom() % (this.max_inter_beat_gap_range - this.min_inter_beat_gap_range)) + this.min_inter_beat_gap_range;

 

Regards,

 

Deanna

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Highlighted
Visitor
Visitor
1,637 Views
Registered: ‎05-07-2018

Hi Deanna,

  I'm using:

# //  Questa Sim-64
# //  Version 10.6d_1 linux_x86_64 Apr 11 2018
# //
# //  Copyright 1991-2018 Mentor Graphics Corporation

 

I'm having trouble with coverage collection.

The problem is data_beat_accepted_cycles is always ZERO.  Despite the waveforms now showing data beat delays.

 

This is part of my coverage collection code:

 

  virtual task monitor_core0(uvm_phase phase);
    forever begin
      env_config_h.event_agent_config_h.axi_vip_core0.monitor.item_collected_port.get(coverage_transaction);

. . .

      foreach(coverage_transaction.data_beat_accepted_cycles[i]) begin
        data_beat_accepted_cycles = coverage_transaction.data_beat_accepted_cycles[i];
        cpu0_data_phase_covergroup.sample();
      end
    end
  endtask

 

0 Kudos