diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_agent_pkg.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_agent_pkg.sv index 1f40b39c..569706df 100644 --- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_agent_pkg.sv +++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_agent_pkg.sv @@ -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" diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent.sv index 0576166e..9001e416 100644 --- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent.sv +++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_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(); diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent_cfg.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent_cfg.sv index 325d5509..caa4e963 100644 --- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent_cfg.sv +++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent_cfg.sv @@ -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; diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_driver.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_driver.sv index a01253ab..36913814 100644 --- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_driver.sv +++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_driver.sv @@ -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 diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_seq_lib.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_seq_lib.sv index fbf0c380..969acac6 100644 --- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_seq_lib.sv +++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_seq_lib.sv @@ -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") diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_sequencer.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_sequencer.sv index dfa8c042..77a66643 100644 --- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_sequencer.sv +++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_sequencer.sv @@ -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)