mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-23 13:27:10 -04:00
Pass mem_err_shift to the ICache memory model on each error check
This has no immediate effect, but it means that the memory agent's config's "mem_err_shift" value can be changed in the middle of the test, rather than being fixed in the build_phase.
This commit is contained in:
parent
48febdc5d6
commit
b49f153a50
3 changed files with 18 additions and 23 deletions
10
dv/uvm/icache/dv/env/ibex_icache_scoreboard.sv
vendored
10
dv/uvm/icache/dv/env/ibex_icache_scoreboard.sv
vendored
|
@ -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];
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue