diff --git a/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_agent.core b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_agent.core index f00bda07..33cd1c97 100644 --- a/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_agent.core +++ b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_agent.core @@ -13,7 +13,8 @@ filesets: - ibex_icache_core_if.sv - ibex_icache_core_protocol_checker.sv - ibex_icache_core_agent_pkg.sv - - ibex_icache_core_item.sv: {is_include_file: true} + - ibex_icache_core_req_item.sv: {is_include_file: true} + - ibex_icache_core_rsp_item.sv: {is_include_file: true} - ibex_icache_core_bus_item.sv: {is_include_file: true} - ibex_icache_core_agent_cfg.sv: {is_include_file: true} - ibex_icache_core_agent_cov.sv: {is_include_file: true} diff --git a/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_agent_pkg.sv b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_agent_pkg.sv index 56f95ef3..fde2f1e8 100644 --- a/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_agent_pkg.sv +++ b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_agent_pkg.sv @@ -26,7 +26,8 @@ package ibex_icache_core_agent_pkg; `include "dv_macros.svh" // package sources - `include "ibex_icache_core_item.sv" + `include "ibex_icache_core_req_item.sv" + `include "ibex_icache_core_rsp_item.sv" `include "ibex_icache_core_bus_item.sv" `include "ibex_icache_core_agent_cfg.sv" `include "ibex_icache_core_agent_cov.sv" diff --git a/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_driver.sv b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_driver.sv index 22986ee2..f12bb1c1 100644 --- a/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_driver.sv +++ b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_driver.sv @@ -2,7 +2,10 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 -class ibex_icache_core_driver extends dv_base_driver #(ibex_icache_core_item, ibex_icache_core_agent_cfg); +class ibex_icache_core_driver + extends dv_base_driver #(.ITEM_T (ibex_icache_core_req_item), + .RSP_ITEM_T (ibex_icache_core_rsp_item), + .CFG_T (ibex_icache_core_agent_cfg)); `uvm_component_utils(ibex_icache_core_driver) `uvm_component_new @@ -18,18 +21,25 @@ class ibex_icache_core_driver extends dv_base_driver #(ibex_icache_core_item, ib // drive trans received from sequencer virtual task automatic get_and_drive(); + ibex_icache_core_rsp_item rsp; + forever begin seq_item_port.get_next_item(req); `uvm_info(`gfn, $sformatf("rcvd item:\n%0s", req.sprint()), UVM_HIGH) + rsp = ibex_icache_core_rsp_item::type_id::create("rsp"); + rsp.set_id_info(req); + + rsp.saw_error = 1'b0; + case (req.trans_type) - ICacheCoreTransTypeBranch: drive_branch_trans(req); - ICacheCoreTransTypeReq: drive_req_trans(req); + ICacheCoreTransTypeBranch: drive_branch_trans(rsp, req); + ICacheCoreTransTypeReq: drive_req_trans(rsp, req); default: `uvm_fatal(`gfn, "Unknown transaction type") endcase `uvm_info(`gfn, "item sent", UVM_HIGH) - seq_item_port.item_done(); + seq_item_port.item_done(rsp); end endtask @@ -37,7 +47,8 @@ class ibex_icache_core_driver extends dv_base_driver #(ibex_icache_core_item, ib // // This concurrently asserts branch with a given address for a cycle while doing the usual // (enable/disable, invalidate, read instructions). - virtual task automatic drive_branch_trans(ibex_icache_core_item req); + task automatic drive_branch_trans(ibex_icache_core_rsp_item rsp, + ibex_icache_core_req_item req); // Make sure that req is enabled (has no effect unless this is the first transaction) cfg.vif.driver_cb.req <= 1'b1; @@ -49,7 +60,7 @@ class ibex_icache_core_driver extends dv_base_driver #(ibex_icache_core_item, ib fork cfg.vif.branch_to(req.branch_addr); if (req.invalidate) invalidate(); - read_insns(req.num_insns); + read_insns(rsp, req.num_insns); join endtask @@ -57,7 +68,8 @@ class ibex_icache_core_driver extends dv_base_driver #(ibex_icache_core_item, ib // // This lowers req for zero or more cycles, at the same time as setting the enable pin and (maybe) // pulsing the invalidate line. Once that is done, it reads zero or more instructions. - virtual task automatic drive_req_trans(ibex_icache_core_item req); + task automatic drive_req_trans(ibex_icache_core_rsp_item rsp, + ibex_icache_core_req_item req); int unsigned req_low_cycles; bit allow_no_low_cycles; @@ -80,16 +92,19 @@ class ibex_icache_core_driver extends dv_base_driver #(ibex_icache_core_item, ib if (req_low_cycles > 0) lower_req(req_low_cycles); if (req.invalidate) invalidate(); join - read_insns(req.num_insns); + read_insns(rsp, req.num_insns); endtask - // Read up to num_insns instructions from the cache, stopping early on an error - virtual task automatic read_insns(int num_insns); + // Read up to num_insns instructions from the cache, stopping early on an error. If there was an + // error, fill in the saw_error flag in rsp (which will be passed back to the sequence). + task automatic read_insns(ibex_icache_core_rsp_item rsp, int num_insns); for (int i = 0; i < num_insns; i++) begin read_insn(); // Spot any error and exit early - if (cfg.vif.driver_cb.err) + if (cfg.vif.driver_cb.err) begin + rsp.saw_error = 1'b1; break; + end end endtask diff --git a/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_item.sv b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_req_item.sv similarity index 96% rename from dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_item.sv rename to dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_req_item.sv index b89faa84..ff84654c 100644 --- a/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_item.sv +++ b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_req_item.sv @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 -class ibex_icache_core_item extends uvm_sequence_item; +class ibex_icache_core_req_item extends uvm_sequence_item; // The type of transaction rand ibex_icache_core_trans_type_e trans_type; @@ -62,7 +62,7 @@ class ibex_icache_core_item extends uvm_sequence_item; } - `uvm_object_utils_begin(ibex_icache_core_item) + `uvm_object_utils_begin(ibex_icache_core_req_item) `uvm_field_enum(ibex_icache_core_trans_type_e, trans_type, UVM_DEFAULT) `uvm_field_int (branch_addr, UVM_DEFAULT | UVM_HEX) `uvm_field_int (toggle_enable, UVM_DEFAULT) diff --git a/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_rsp_item.sv b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_rsp_item.sv new file mode 100644 index 00000000..ebbc5f88 --- /dev/null +++ b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_rsp_item.sv @@ -0,0 +1,19 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class ibex_icache_core_rsp_item extends uvm_sequence_item; + + // A sequence item that is used for responses from the driver back to the sequence. This is needed + // so that we can spot when there was an error signalled by the core (which means the next + // sequence item will need to be a branch). + + bit saw_error; + + `uvm_object_utils_begin(ibex_icache_core_rsp_item) + `uvm_field_int (saw_error, UVM_DEFAULT) + `uvm_object_utils_end + + `uvm_object_new + +endclass diff --git a/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_sequencer.sv b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_sequencer.sv index c2e0e3fe..48c234f9 100644 --- a/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_sequencer.sv +++ b/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_sequencer.sv @@ -2,8 +2,10 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 -class ibex_icache_core_sequencer extends dv_base_sequencer #(.ITEM_T (ibex_icache_core_item), - .CFG_T (ibex_icache_core_agent_cfg)); +class ibex_icache_core_sequencer + extends dv_base_sequencer #(.ITEM_T (ibex_icache_core_req_item), + .RSP_ITEM_T (ibex_icache_core_rsp_item), + .CFG_T (ibex_icache_core_agent_cfg)); `uvm_component_utils(ibex_icache_core_sequencer) `uvm_component_new diff --git a/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_base_seq.sv b/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_base_seq.sv index 15b03850..03cd31af 100644 --- a/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_base_seq.sv +++ b/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_base_seq.sv @@ -3,7 +3,8 @@ // SPDX-License-Identifier: Apache-2.0 class ibex_icache_core_base_seq extends dv_base_seq #( - .REQ (ibex_icache_core_item), + .REQ (ibex_icache_core_req_item), + .RSP (ibex_icache_core_rsp_item), .CFG_T (ibex_icache_core_agent_cfg), .SEQUENCER_T (ibex_icache_core_sequencer) ); diff --git a/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_sanity_seq.sv b/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_sanity_seq.sv index 23aa8f81..18f774c3 100644 --- a/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_sanity_seq.sv +++ b/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_sanity_seq.sv @@ -13,19 +13,26 @@ class ibex_icache_core_sanity_seq extends ibex_icache_core_base_seq; constraint c_count { count > 0; count < 100; } task body(); - // Generate a request which is constrained to have trans_type ICacheCoreTransTypeBranch: the - // core must start with a branch to tell the cache where to fetch from in the first place. - req = ibex_icache_core_item::type_id::create("req"); - start_item(req); - `DV_CHECK_RANDOMIZE_WITH_FATAL(req, req.trans_type == ICacheCoreTransTypeBranch;) - finish_item(req); + // If this is set, the next request will be constrained to have trans_type + // ICacheCoreTransTypeBranch. It's initially 1 because the core must start with a branch to tell + // the cache where to fetch from in the first place. + bit force_branch = 1'b1; + + req = ibex_icache_core_req_item::type_id::create("req"); + rsp = ibex_icache_core_rsp_item::type_id::create("rsp"); - // Generate and run count ibex_icache_item sequence items (with no other constraint) through the - // req port. repeat (count - 1) begin start_item(req); - `DV_CHECK_RANDOMIZE_FATAL(req) + if (force_branch) begin + `DV_CHECK_RANDOMIZE_WITH_FATAL(req, req.trans_type == ICacheCoreTransTypeBranch;) + end else begin + `DV_CHECK_RANDOMIZE_FATAL(req) + end finish_item(req); + get_response(rsp); + + // The next transaction must start with a branch if this one ended with an error. + force_branch = rsp.saw_error; end endtask endclass