diff --git a/dv/uvm/icache/dv/env/ibex_icache_scoreboard.sv b/dv/uvm/icache/dv/env/ibex_icache_scoreboard.sv index 875b8362..cb7bb619 100644 --- a/dv/uvm/icache/dv/env/ibex_icache_scoreboard.sv +++ b/dv/uvm/icache/dv/env/ibex_icache_scoreboard.sv @@ -119,8 +119,7 @@ class ibex_icache_scoreboard seed_fifo = new("seed_fifo", this); mem_model = new("mem_model", cfg.mem_agent_cfg.disable_pmp_errs, - cfg.mem_agent_cfg.disable_mem_errs, - cfg.mem_agent_cfg.mem_err_shift); + cfg.mem_agent_cfg.disable_mem_errs); endfunction task run_phase(uvm_phase phase); @@ -406,7 +405,8 @@ class ibex_icache_scoreboard return is_fetch_compatible_1(seen_insn_data, seen_err, - mem_model.is_either_error(seed, addr_lo), + mem_model.is_either_error(seed, addr_lo, + cfg.mem_agent_cfg.mem_err_shift), rdata[31:0], seed, chatty); @@ -445,13 +445,13 @@ class ibex_icache_scoreboard lo_bits_to_drop = BusWidth - lo_bits_to_take; // Do the first read (from the low address) and shift right to drop the bits that we don't need. - exp_err_lo = mem_model.is_either_error(seed_lo, addr_lo); + exp_err_lo = mem_model.is_either_error(seed_lo, addr_lo, cfg.mem_agent_cfg.mem_err_shift); rdata = mem_model.read_data(seed_lo, addr_lo) >> lo_bits_to_drop; exp_data = rdata[31:0]; // Now do the second read (from the upper address). Shift the result up by lo_bits_to_take, // which will discard some top bits. Then extract 32 bits and OR with what we have so far. - exp_err_hi = mem_model.is_either_error(seed_hi, addr_hi); + exp_err_hi = mem_model.is_either_error(seed_hi, addr_hi, cfg.mem_agent_cfg.mem_err_shift); rdata = mem_model.read_data(seed_hi, addr_hi) << lo_bits_to_take; exp_data = exp_data | rdata[31:0]; diff --git a/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_model.sv b/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_model.sv index 6d163e73..8196d5d2 100644 --- a/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_model.sv +++ b/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_model.sv @@ -29,29 +29,24 @@ class ibex_icache_mem_model #(parameter int unsigned BusWidth = 32) extends uvm_ // If set, disable memory errors protected bit no_mem_errs; - // The power of two by which to divide the address space to get the error range: see is_error for - // details. - protected int unsigned error_shift; - function new(string name="", bit disable_pmp_errs=0, - bit disable_mem_errs=0, - int unsigned err_shift=3); + bit disable_mem_errs=0); no_pmp_errs = disable_pmp_errs; no_mem_errs = disable_mem_errs; - error_shift = err_shift; endfunction `uvm_object_utils_begin(ibex_icache_mem_model) `uvm_field_int (no_pmp_errs, UVM_DEFAULT) `uvm_field_int (no_mem_errs, UVM_DEFAULT) - `uvm_field_int (error_shift, UVM_DEFAULT) `uvm_object_utils_end // Return true if reading BusWidth bits from address intersects with the error range given by the // current seed. The error range has a length of (1/2^error_shift) times the size of the address // space. - protected function automatic logic is_error(bit [31:0] seed, logic [31:0] address); + protected function automatic logic + is_error(bit [31:0] seed, logic [31:0] address, int unsigned error_shift); + logic [31:0] rng_lo, rng_hi, rng_w0, rng_w1; rng_lo = seed ^ 32'hdeadbeef; rng_w0 = 32'd1 << (32 - error_shift); @@ -65,18 +60,18 @@ class ibex_icache_mem_model #(parameter int unsigned BusWidth = 32) extends uvm_ endfunction // Return true if reading BusWidth bits from address should give a PMP error - function automatic logic is_pmp_error(bit [31:0] seed, logic [31:0] address); - return (! no_pmp_errs) && is_error(seed, address ^ 32'h12344321); + function automatic logic is_pmp_error(bit [31:0] seed, logic [31:0] addr, int unsigned err_shift); + return (! no_pmp_errs) && is_error(seed, addr ^ 32'h12344321, err_shift); endfunction // Return true if reading BusWidth bits from address should give a memory error - function automatic logic is_mem_error(bit [31:0] seed, logic [31:0] address); - return (! no_mem_errs) && is_error(seed, address ^ 32'hf00dbeef); + function automatic logic is_mem_error(bit [31:0] seed, logic [31:0] addr, int unsigned err_shift); + return (! no_mem_errs) && is_error(seed, addr ^ 32'hf00dbeef, err_shift); endfunction // Return true if reading BusWidth bits from address should give some sort of error - function automatic logic is_either_error(bit [31:0] seed, logic [31:0] address); - return is_pmp_error(seed, address) || is_mem_error(seed, address); + function automatic logic is_either_error(bit [31:0] seed, logic [31:0] addr, int unsigned err_shift); + return is_pmp_error(seed, addr, err_shift) || is_mem_error(seed, addr, err_shift); endfunction // Return BusWidth bits of data from reading at address. diff --git a/dv/uvm/icache/dv/ibex_icache_mem_agent/seq_lib/ibex_icache_mem_resp_seq.sv b/dv/uvm/icache/dv/ibex_icache_mem_agent/seq_lib/ibex_icache_mem_resp_seq.sv index ad4a3a6f..7a9151b1 100644 --- a/dv/uvm/icache/dv/ibex_icache_mem_agent/seq_lib/ibex_icache_mem_resp_seq.sv +++ b/dv/uvm/icache/dv/ibex_icache_mem_agent/seq_lib/ibex_icache_mem_resp_seq.sv @@ -32,7 +32,7 @@ class ibex_icache_mem_resp_seq extends ibex_icache_mem_base_seq; task pre_start(); super.pre_start(); - mem_model = new("mem_model", cfg.disable_pmp_errs, cfg.disable_mem_errs, cfg.mem_err_shift); + mem_model = new("mem_model", cfg.disable_pmp_errs, cfg.disable_mem_errs); endtask task body(); @@ -75,7 +75,7 @@ class ibex_icache_mem_resp_seq extends ibex_icache_mem_base_seq; resp_item.is_grant = 1'b0; resp_item.address = req_item.address; resp_item.rdata = 'X; - resp_item.err = mem_model.is_pmp_error(cur_seed, req_item.address); + resp_item.err = mem_model.is_pmp_error(cur_seed, req_item.address, cfg.mem_err_shift); start_item(resp_item); `DV_CHECK_RANDOMIZE_FATAL(resp_item) @@ -116,7 +116,7 @@ class ibex_icache_mem_resp_seq extends ibex_icache_mem_base_seq; // Using the seed that we saw for the request, check the memory model for a (non-PMP) error // at this address. On success, look up the memory data too. resp_item.is_grant = 1'b1; - resp_item.err = mem_model.is_mem_error(gnt_seed, req_item.address); + resp_item.err = mem_model.is_mem_error(gnt_seed, req_item.address, cfg.mem_err_shift); resp_item.address = req_item.address; resp_item.rdata = resp_item.err ? 'X : mem_model.read_data(gnt_seed, req_item.address);