AXI Slave Read Driver object.It does below:
Receives AR Command from the interface and then passes that command to the user environment. The user will then create a READ transaction and pass it back to the driver to drive the R channel.
Trigger an event when the AR Command is accepted.
Trigger an event when the RLAST is accepted.
Receives READY transactions from the user environment and drives the ARREADY signal of the AR channel.
Drives the R channel.
Configurable command re-ordering.
axi_vif_mem_proxy `AXI_PARAM_ORDER vif_proxy; AXI VIF Proxy Class
xil_seq_item_pull_port #(axi_transaction,axi_transaction) seq_item_port; provides method to send read transaction to axi_slv_rd_driver.
xil_seq_item_pull_port #(axi_ready_gen, axi_ready_gen) arready_seq_item_port; provides the method to send arready information to axi_slv_rd_driver.
function new( |
| ); |
Constructor to create an AXI slave read driver
function void set_reorder_data_ability ( |
| ); |
Sets reorder_data_ability of the slave read driver. please refer <set_xfer_preemptive_probability> in axi_transaction for more information.
Returns reorder_data_ability of the slave read driver. please refer <set_xfer_preemptive_probability> in axi_transaction for more information.
function void set_vif( |
| ); |
Assigns the virtual interface of the driver.
function void set_arready_gen( |
| ); |
Sets arready of the AXI slave read driver. There are three ways for arready generation in AXI slave read driver.
1.User can first create a axi_ready_gen, customerize it and then use set_arready_gen to send it to AXI slave read driver.
2.User can can first create a axi_ready_gen, customerize it and then use send_arready to send it to AXI slave read driver.
3. If neither of above method is being called, then AXI slave read driver will a) if XIL_DO_NOT_USE_ADV_RANDOMIZATION is being defined, arready is being generated with cheap_random(this is for tools which doesn't support advanced randomization. b) else arready will be randomly generated
Returns the arready_gen of the slave read driver.
function void set_forward_progress_timeout_value ( |
| ); |
Sets the number of cycles that the driver will wait until it will flag a watch dog error of the axi_slv_rd_driver. Default value is 50000. Setting this to a very large value will cause a hung simulation to continue for a longer time. Setting this to a very small number may not allow enough time for simulation to respond.
Returns the number of cycles that the driver will wait until it will flag a watch dog error of the axi_slv_rd_driver. Default value is 50000 and user can use set_forward_progress_timeout_value to change it.
function void set_waiting_valid_timeout_value ( |
| ); |
Sets waiting_valid_timeout_value of the slave read driver. waiting_valid_timeout_value is used for driver to wait a certain number of cycles for rvalid/rready handshake occurs before it time out.
Returns waiting_valid_timeout_value of the Driver
function void set_transaction_depth( |
| ); |
Returns the maximum number of READ transactions that the Driver will have in flight at one time.
Returns the maximum number of READ transactions that the Driver will have in flight at one time.
Returns number of commands in pending
Start control processes for operation
Stops all control processes.
virtual function axi_transaction create_transaction ( |
| ); |
Returns an AXI transaction class that has been "newed"
task get_rd_reactive ( |
| ); |
Returns Read reactive transaction with read command information. When Slave VIP instantiate agent without memory, user can use this API to create an AXI transaction,fill in data information and send it back to Slave VIP interface.
The usage of this API is shown below and it MUST be put in initial, forever procedure since get_rd_reactive is blocking, so does send. Please refer example design simset sim_allconfig for function of fill_payload, fill_ruser, and fill_beat_delay etc.
initial begin
forever begin
slv_agent.rd_driver.get_rd_reactive(rd_reactive);
fill_payload(rd_reactive);
//fill in user information if ruser width is not 0.
if (c_ruser_width ne 0 ) begin
fill_ruser(rd_reactive);
end
fill_beat_delay(rd_reactive);
slv_agent.rd_driver.send(rd_reactive);
end
end
//Function for read transaction which fill data into transaction according to related address of
//the transaction and existence in memory
function automatic void fill_payload(inout axi_transaction t);
longint unsigned current_addr;
longint unsigned addr_max;
xil_axi_payload_byte beat[];
xil_axi_uint start_address;
xil_axi_uint number_bytes;
xil_axi_uint aligned_address;
xil_axi_uint burst_length;
xil_axi_uint address_n;
xil_axi_uint wrap_boundary;
current_addr = t.get_addr();
start_address = t.get_addr();
number_bytes = xil_pow2(t.get_size());
burst_length = t.get_len() + 1;
aligned_address = (start_address/number_bytes) * number_bytes;
wrap_boundary = (start_address/(number_bytes * burst_length)) * (number_bytes * burst_length);
beat = new[(1<<t.get_size())];
for (int beat_cnt = 0; beat_cnt <= t.get_len();beat_cnt++) begin
for (int byte_cnt = 0; byte_cnt < (1<<t.get_size());byte_cnt++) begin
if (!data_mem.exists(current_addr)) begin
data_mem[current_addr] = {$random};
end
beat[byte_cnt] = data_mem[current_addr];
current_addr += 1;
end
if(t.get_burst() == XIL_AXI_BURST_TYPE_WRAP) begin
if (current_addr >= wrap_boundary + (number_bytes*burst_length)) begin
current_addr = wrap_boundary + (current_addr - wrap_boundary - (number_bytes*burst_length));
end
end else if(t.get_burst() == XIL_AXI_BURST_TYPE_FIXED) begin
current_addr = start_address;
end else begin
current_addr = current_addr;
end
t.set_data_beat_unpacked(t.get_beat_index(),beat);
t.increment_beat_index();
end
t.clr_beat_index();
endfunction: fill_payload
// fill user info into transaction
function automatic void fill_ruser(inout axi_transaction t);
xil_axi_user_beat ruser;
for (int beat_cnt = 0; beat_cnt <= t.get_len();beat_cnt++) begin
ruser = {$random};
t.set_ruser(beat_cnt,ruser);
end
endfunction: fill_ruser
//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
task send_arready( |
| ); |
Sends the ready structure to the driver for controlling the ARREADY channel. This is blocking process which will not return till this ready is being sent out.
virtual function axi_ready_gen create_ready ( |
| ); |
Returns a ready class in the slave read driver that has been "newed" with instance name ~name~.
task send( |
| ); |
Sends the AXI transaction to the slave read driver. This is blocking process which will not return till this transaction is being sent out.
task wait_rsp( |
| ); |
This blocking function will not return until driver send back response transaction