[dv] Add direct instruction stream to hit pmp boundary cross coverage

The new instruction stream randomly chooses a NAPOT PMP region and emits
a store or load which will cross the boundary of that region at either
the top or the bottom.
This commit is contained in:
Greg Chadwick 2022-11-15 12:25:20 +00:00 committed by Greg Chadwick
parent c48ca23c40
commit fb32236a3f
2 changed files with 92 additions and 0 deletions

View file

@ -147,3 +147,93 @@ class ibex_valid_na4_stream extends riscv_directed_instr_stream;
endfunction
endclass
class ibex_cross_pmp_region_mem_access_stream extends riscv_directed_instr_stream;
`uvm_object_utils(ibex_cross_pmp_region_mem_access_stream)
int unsigned pmp_region;
int unsigned region_mask;
int unsigned region_size;
function new (string name = "");
super.new(name);
endfunction
function void calc_region_params();
int unsigned cur_addr = cfg.pmp_cfg.pmp_cfg[pmp_region].addr;
region_size = 8;
region_mask = 32'hfffffffe;
for (int i = 0; i < 29; ++i) begin
if ((cur_addr & 1) == 0) break;
region_size *= 2;
cur_addr >>= 1;
region_mask <<= 1;
end
endfunction
function int unsigned pmp_region_top_addr();
return ((cfg.pmp_cfg.pmp_cfg[pmp_region].addr & region_mask) << 2) + region_size;
endfunction
function int unsigned pmp_region_bottom_addr();
return ((cfg.pmp_cfg.pmp_cfg[pmp_region].addr & region_mask) << 2);
endfunction
function void post_randomize();
int unsigned target_addr;
int unsigned offset;
riscv_pseudo_instr la_instr;
riscv_instr mem_instr;
bit access_at_top;
if (!std::randomize(pmp_region) with {
pmp_region > 1;
pmp_region < cfg.pmp_cfg.pmp_num_regions;
cfg.pmp_cfg.pmp_cfg[pmp_region].a == NAPOT;
})
begin
`uvm_info(`gfn,
{"WARNING: Cannot choose random NAPOT PMP region, skipping cross PMP region access ",
"generation"}, UVM_LOW)
return;
end
initialize_instr_list(2);
calc_region_params();
mem_instr = riscv_instr::get_load_store_instr({LH, LHU, LW, SH, SW});
std::randomize(access_at_top);
if (mem_instr.instr_name inside {LW, SW}) begin
std::randomize(offset) with {offset < 3;offset > 0;};
end else begin
offset = 1;
end
if (access_at_top) begin
target_addr = pmp_region_top_addr() - offset;
end else begin
target_addr = pmp_region_bottom_addr() - offset;
end
la_instr = riscv_pseudo_instr::type_id::create("la_instr");
la_instr.pseudo_instr_name = LA;
la_instr.has_label = 1'b0;
la_instr.atomic = 1'b1;
la_instr.imm_str = $sformatf("0x%x", target_addr);
la_instr.rd = cfg.gpr[1];
randomize_gpr(mem_instr);
mem_instr.has_imm = 0;
mem_instr.imm_str = "0";
mem_instr.rs1 = cfg.gpr[1];
instr_list = {la_instr, mem_instr};
super.post_randomize();
endfunction
endclass

View file

@ -844,6 +844,8 @@
+directed_instr_3=riscv_load_store_rand_addr_instr_stream,40
+directed_instr_4=ibex_rand_mseccfg_stream,1
+directed_instr_6=ibex_valid_na4_stream,20
+directed_instr_7=ibex_cross_pmp_region_mem_access_stream,10
+enable_unaligned_load_store=1
sim_opts: >
+is_double_fault_detected_fatal=0
+enable_bad_intg_on_uninit_access=0