mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-23 13:27:10 -04:00
[ibex, dv] Makes delays between req, gnt and rvalid configurable
This commit adds functionalty to the memory response agent to make delays more configurable. There are two delays - Delay between req and gnt - Delay between gnt and rvalid For each of these delays we have three modes: * Fully random delay * Fixed delay * Biased delay. Randomised delays but allow biasing towards 0 delay, to give a mix of runs with back to back transfers with no delay and some with delays. Signed-off-by: Prajwala Puttappa <prajwalaputtappa@lowrisc.org>
This commit is contained in:
parent
46c397501d
commit
af0c027867
6 changed files with 73 additions and 60 deletions
|
@ -19,10 +19,10 @@ package ibex_mem_intf_agent_pkg;
|
|||
typedef uvm_sequencer#(ibex_mem_intf_seq_item) ibex_mem_intf_request_sequencer;
|
||||
|
||||
`include "ibex_mem_intf_monitor.sv"
|
||||
`include "ibex_mem_intf_response_agent_cfg.sv"
|
||||
`include "ibex_mem_intf_response_driver.sv"
|
||||
`include "ibex_mem_intf_response_sequencer.sv"
|
||||
`include "ibex_mem_intf_response_seq_lib.sv"
|
||||
`include "ibex_mem_intf_response_agent_cfg.sv"
|
||||
`include "ibex_mem_intf_response_agent.sv"
|
||||
`include "ibex_mem_intf_request_driver.sv"
|
||||
`include "ibex_mem_intf_request_agent.sv"
|
||||
|
|
|
@ -34,7 +34,8 @@ class ibex_mem_intf_response_agent extends uvm_agent;
|
|||
driver.seq_item_port.connect(sequencer.seq_item_export);
|
||||
monitor.addr_ph_port.connect(sequencer.addr_ph_port.analysis_export);
|
||||
end
|
||||
driver.vif = cfg.vif;
|
||||
driver.cfg = cfg;
|
||||
sequencer.cfg = cfg;
|
||||
endfunction : connect_phase
|
||||
|
||||
function void reset();
|
||||
|
|
|
@ -13,11 +13,17 @@ class ibex_mem_intf_response_agent_cfg extends uvm_object;
|
|||
|
||||
// delay between request and grant
|
||||
int unsigned gnt_delay_min = 0;
|
||||
int unsigned gnt_delay_max = 1000;
|
||||
int unsigned gnt_delay_max = 10;
|
||||
// Pick the weight assigned to choosing medium and long gaps between request and grant
|
||||
int unsigned gnt_pick_medium_speed_weight = 1;
|
||||
int unsigned gnt_pick_slow_speed_weight = 1;
|
||||
|
||||
// delay between grant and rvalid
|
||||
int unsigned valid_delay_min = 1;
|
||||
int unsigned valid_delay_max = 1000;
|
||||
int unsigned valid_delay_min = 0;
|
||||
int unsigned valid_delay_max = 20;
|
||||
// Pick the weight assigned to choosing medium and long gaps between grant and rvalid
|
||||
int unsigned valid_pick_medium_speed_weight = 1;
|
||||
int unsigned valid_pick_slow_speed_weight = 1;
|
||||
|
||||
// Enables/disable all protocol delays.
|
||||
rand bit zero_delays;
|
||||
|
|
|
@ -8,10 +8,7 @@
|
|||
|
||||
class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item);
|
||||
|
||||
virtual ibex_mem_intf vif;
|
||||
|
||||
int unsigned min_grant_delay = 0;
|
||||
int unsigned max_grant_delay = 10;
|
||||
ibex_mem_intf_response_agent_cfg cfg;
|
||||
|
||||
`uvm_component_utils(ibex_mem_intf_response_driver)
|
||||
`uvm_component_new
|
||||
|
@ -25,12 +22,12 @@ class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item)
|
|||
|
||||
virtual task run_phase(uvm_phase phase);
|
||||
reset_signals();
|
||||
wait (vif.response_driver_cb.reset === 1'b0);
|
||||
wait (cfg.vif.response_driver_cb.reset === 1'b0);
|
||||
forever begin
|
||||
fork : drive_stimulus
|
||||
send_grant();
|
||||
get_and_drive();
|
||||
wait (vif.response_driver_cb.reset === 1'b1);
|
||||
wait (cfg.vif.response_driver_cb.reset === 1'b1);
|
||||
join_any
|
||||
// Will only be reached after mid-test reset
|
||||
disable fork;
|
||||
|
@ -50,27 +47,27 @@ class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item)
|
|||
end
|
||||
end while (req != null);
|
||||
reset_signals();
|
||||
wait (vif.response_driver_cb.reset === 1'b0);
|
||||
wait (cfg.vif.response_driver_cb.reset === 1'b0);
|
||||
endtask
|
||||
|
||||
virtual protected task reset_signals();
|
||||
vif.response_driver_cb.rvalid <= 1'b0;
|
||||
vif.response_driver_cb.grant <= 1'b0;
|
||||
vif.response_driver_cb.rdata <= 'b0;
|
||||
vif.response_driver_cb.rintg <= 'b0;
|
||||
vif.response_driver_cb.error <= 1'b0;
|
||||
cfg.vif.response_driver_cb.rvalid <= 1'b0;
|
||||
cfg.vif.response_driver_cb.grant <= 1'b0;
|
||||
cfg.vif.response_driver_cb.rdata <= 'b0;
|
||||
cfg.vif.response_driver_cb.rintg <= 'b0;
|
||||
cfg.vif.response_driver_cb.error <= 1'b0;
|
||||
endtask : reset_signals
|
||||
|
||||
virtual protected task get_and_drive();
|
||||
wait (vif.response_driver_cb.reset === 1'b0);
|
||||
wait (cfg.vif.response_driver_cb.reset === 1'b0);
|
||||
fork
|
||||
begin
|
||||
forever begin
|
||||
ibex_mem_intf_seq_item req, req_c;
|
||||
vif.wait_clks(1);
|
||||
cfg.vif.wait_clks(1);
|
||||
seq_item_port.get_next_item(req);
|
||||
$cast(req_c, req.clone());
|
||||
if(~vif.response_driver_cb.reset) begin
|
||||
if(~cfg.vif.response_driver_cb.reset) begin
|
||||
rdata_queue.put(req_c);
|
||||
end
|
||||
seq_item_port.item_done();
|
||||
|
@ -85,23 +82,27 @@ class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item)
|
|||
virtual protected task send_grant();
|
||||
int gnt_delay;
|
||||
forever begin
|
||||
while(vif.response_driver_cb.request !== 1'b1) begin
|
||||
vif.wait_neg_clks(1);
|
||||
while(cfg.vif.response_driver_cb.request !== 1'b1) begin
|
||||
cfg.vif.wait_neg_clks(1);
|
||||
end
|
||||
if (!std::randomize(gnt_delay) with {
|
||||
gnt_delay dist {
|
||||
min_grant_delay :/ 1,
|
||||
[min_grant_delay+1 : max_grant_delay-1] :/ 1,
|
||||
max_grant_delay :/ 1
|
||||
};
|
||||
}) begin
|
||||
`uvm_fatal(`gfn, $sformatf("Cannot randomize grant"))
|
||||
if(cfg.zero_delays) begin
|
||||
gnt_delay = 0;
|
||||
end else begin
|
||||
if (!std::randomize(gnt_delay) with {
|
||||
gnt_delay dist {
|
||||
cfg.gnt_delay_min :/ 10,
|
||||
[cfg.gnt_delay_min+1 : cfg.gnt_delay_max-1] :/ cfg.valid_pick_medium_speed_weight,
|
||||
cfg.gnt_delay_max :/ cfg.valid_pick_slow_speed_weight
|
||||
};
|
||||
}) begin
|
||||
`uvm_fatal(`gfn, $sformatf("Cannot randomize grant"))
|
||||
end
|
||||
end
|
||||
vif.wait_neg_clks(gnt_delay);
|
||||
if(~vif.response_driver_cb.reset) begin
|
||||
vif.response_driver_cb.grant <= 1'b1;
|
||||
vif.wait_neg_clks(1);
|
||||
vif.response_driver_cb.grant <= 1'b0;
|
||||
cfg.vif.wait_neg_clks(gnt_delay);
|
||||
if(~cfg.vif.response_driver_cb.reset) begin
|
||||
cfg.vif.response_driver_cb.grant <= 1'b1;
|
||||
cfg.vif.wait_neg_clks(1);
|
||||
cfg.vif.response_driver_cb.grant <= 1'b0;
|
||||
end
|
||||
end
|
||||
endtask : send_grant
|
||||
|
@ -109,19 +110,19 @@ class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item)
|
|||
virtual protected task send_read_data();
|
||||
ibex_mem_intf_seq_item tr;
|
||||
forever begin
|
||||
vif.wait_clks(1);
|
||||
vif.response_driver_cb.rvalid <= 1'b0;
|
||||
vif.response_driver_cb.rdata <= 'x;
|
||||
vif.response_driver_cb.rintg <= 'x;
|
||||
vif.response_driver_cb.error <= 'x;
|
||||
cfg.vif.wait_clks(1);
|
||||
cfg.vif.response_driver_cb.rvalid <= 1'b0;
|
||||
cfg.vif.response_driver_cb.rdata <= 'x;
|
||||
cfg.vif.response_driver_cb.rintg <= 'x;
|
||||
cfg.vif.response_driver_cb.error <= 'x;
|
||||
rdata_queue.get(tr);
|
||||
if(vif.response_driver_cb.reset) continue;
|
||||
vif.wait_clks(tr.rvalid_delay);
|
||||
if(~vif.response_driver_cb.reset) begin
|
||||
vif.response_driver_cb.rvalid <= 1'b1;
|
||||
vif.response_driver_cb.error <= tr.error;
|
||||
vif.response_driver_cb.rdata <= tr.data;
|
||||
vif.response_driver_cb.rintg <= tr.intg;
|
||||
if(cfg.vif.response_driver_cb.reset) continue;
|
||||
cfg.vif.wait_clks(tr.rvalid_delay);
|
||||
if(~cfg.vif.response_driver_cb.reset) begin
|
||||
cfg.vif.response_driver_cb.rvalid <= 1'b1;
|
||||
cfg.vif.response_driver_cb.error <= tr.error;
|
||||
cfg.vif.response_driver_cb.rdata <= tr.data;
|
||||
cfg.vif.response_driver_cb.rintg <= tr.intg;
|
||||
end
|
||||
end
|
||||
endtask : send_read_data
|
||||
|
|
|
@ -8,15 +8,13 @@
|
|||
|
||||
class ibex_mem_intf_response_seq extends uvm_sequence #(ibex_mem_intf_seq_item);
|
||||
|
||||
int max_rvalid_delay = 20;
|
||||
int min_rvalid_delay = 0;
|
||||
ibex_mem_intf_seq_item item;
|
||||
mem_model m_mem;
|
||||
bit enable_error = 1'b0;
|
||||
ibex_mem_intf_seq_item item;
|
||||
mem_model m_mem;
|
||||
bit enable_error = 1'b0;
|
||||
// Used to ensure that whenever inject_error() is called, the very next transaction will inject an
|
||||
// error, and that enable_error will not be flipped back to 0 immediately
|
||||
bit error_synch = 1'b1;
|
||||
bit is_dmem_seq = 1'b0;
|
||||
bit error_synch = 1'b1;
|
||||
bit is_dmem_seq = 1'b0;
|
||||
|
||||
`uvm_object_utils(ibex_mem_intf_response_seq)
|
||||
`uvm_declare_p_sequencer(ibex_mem_intf_response_sequencer)
|
||||
|
@ -41,12 +39,18 @@ class ibex_mem_intf_response_seq extends uvm_sequence #(ibex_mem_intf_seq_item);
|
|||
data == item.data;
|
||||
intg == item.intg;
|
||||
be == item.be;
|
||||
rvalid_delay dist {
|
||||
min_rvalid_delay :/ 5,
|
||||
[min_rvalid_delay + 1 : max_rvalid_delay / 2 - 1] :/ 3,
|
||||
[max_rvalid_delay / 2 : max_rvalid_delay - 1] :/ 1,
|
||||
max_rvalid_delay :/ 1
|
||||
};
|
||||
if (p_sequencer.cfg.zero_delays) {
|
||||
rvalid_delay == 0;
|
||||
} else {
|
||||
rvalid_delay dist {
|
||||
p_sequencer.cfg.valid_delay_min :/ 5,
|
||||
[p_sequencer.cfg.valid_delay_min + 1 : p_sequencer.cfg.valid_delay_max / 2 - 1] :/ 3,
|
||||
[p_sequencer.cfg.valid_delay_max / 2 : p_sequencer.cfg.valid_delay_max - 1]
|
||||
:/ p_sequencer.cfg.valid_pick_medium_speed_weight,
|
||||
p_sequencer.cfg.valid_delay_max
|
||||
:/ p_sequencer.cfg.valid_pick_slow_speed_weight
|
||||
};
|
||||
}
|
||||
error == enable_error;
|
||||
}) begin
|
||||
`uvm_fatal(`gfn, "Cannot randomize response request")
|
||||
|
|
|
@ -10,6 +10,7 @@ class ibex_mem_intf_response_sequencer extends uvm_sequencer #(ibex_mem_intf_seq
|
|||
|
||||
// TLM port to peek the address phase from the response monitor
|
||||
uvm_tlm_analysis_fifo #(ibex_mem_intf_seq_item) addr_ph_port;
|
||||
ibex_mem_intf_response_agent_cfg cfg;
|
||||
|
||||
`uvm_component_utils(ibex_mem_intf_response_sequencer)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue