blob: 22f8b00b6d126f7655a7236f6c83e9936bac9b7f [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// This test creates read buffer eviction by program_flash operation.
class flash_ctrl_rw_evict_vseq extends flash_ctrl_legacy_base_vseq;
`uvm_object_utils(flash_ctrl_rw_evict_vseq)
`uvm_object_new
virtual task body();
int page;
int evict_trans, idx = 0;
int evict_start = 0;
rd_cache_t addr_q[$];
flash_op_t init_ctrl;
flash_dv_part_e part;
bank = $urandom_range(0, 1);
fork
begin
rd_cache_t entry;
while (idx < 50 && cfg.flash_ctrl_vif.fatal_err == 0) begin
`DV_CHECK_RANDOMIZE_FATAL(this)
rand_op.addr[OTFBankId] = bank;
ctrl = rand_op;
if (evict_start) begin
addr_q.shuffle();
entry = addr_q[0];
ctrl.otf_addr = entry.addr;
ctrl.partition = entry.part;
init_ctrl = ctrl;
send_evict(ctrl, bank);
ctrl = init_ctrl;
if (ctrl.partition == FlashPartData) begin
randcase
1: readback_flash(ctrl, bank, 1, fractions);
1: direct_readback(ctrl.otf_addr, bank, 1);
endcase
end else begin
readback_flash(ctrl, bank, 1, fractions);
end
end else begin
entry.bank = bank;
entry.addr = ctrl.otf_addr;
entry.part = ctrl.partition;
if (ctrl.partition == FlashPartData) begin
randcase
1: begin
int size, is_odd, tail;
is_odd = ctrl.addr[2];
size = (fractions + is_odd) / 2;
tail = (fractions + is_odd) % 2;
repeat (size) begin
addr_q.push_back(entry);
if (addr_q.size > 4) begin
rd_cache_t old_ent = addr_q.pop_front();
end
entry.addr += 8;
end
if (tail) begin
addr_q.push_back(entry);
if (addr_q.size > 4) begin
rd_cache_t old_ent = addr_q.pop_front();
end
end
readback_flash(ctrl, bank, 1, fractions);
end
3: begin
addr_q.push_back(entry);
if (addr_q.size > 4) begin
rd_cache_t old_ent = addr_q.pop_front();
end
direct_readback(ctrl.otf_addr, bank, 1);
end
endcase
end else begin
int size, is_odd, tail;
is_odd = ctrl.addr[2];
size = (fractions + is_odd) / 2;
tail = (fractions + is_odd) % 2;
repeat (size) begin
addr_q.push_back(entry);
if (addr_q.size > 4) begin
rd_cache_t old_ent = addr_q.pop_front();
end
entry.addr += 8;
end
if (tail) begin
addr_q.push_back(entry);
if (addr_q.size > 4) begin
rd_cache_t old_ent = addr_q.pop_front();
end
end
readback_flash(ctrl, bank, 1, fractions);
end
`uvm_info("seq", $sformatf("idx:%0d done",idx), UVM_HIGH)
end // else: !if(evct_start)
idx++;
end // while (idx < 30 && cfg.flash_ctrl_vif.fatal_err == 0)
`uvm_info("seq",
$sformatf("read complete fatal:%0d", cfg.flash_ctrl_vif.fatal_err), UVM_HIGH)
end // fork begin
begin
time timeout_ns = 100_000_000;
evict_trans = $urandom_range(10, 20);
`uvm_info("seq", $sformatf("wait evict start %0d", evict_trans), UVM_MEDIUM)
`DV_SPINWAIT( wait(idx == evict_trans);,
$sformatf("Timed out waiting for evict trans %0d idx:%0d",
evict_trans, idx), timeout_ns,
"seq")
evict_start = 1;
end
join
cfg.seq_cfg.disable_flash_init = 1;
endtask
virtual task send_evict(flash_op_t ctrl, int bank);
prog_flash(ctrl, bank, 1, fractions);
endtask // send_evict
endclass // flash_ctrl_rw_evict_vseq