Skip to content

Commit fb32236

Browse files
committed
[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.
1 parent c48ca23 commit fb32236

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

dv/uvm/core_ibex/riscv_dv_extension/ibex_directed_instr_lib.sv

+90
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,93 @@ class ibex_valid_na4_stream extends riscv_directed_instr_stream;
147147
endfunction
148148

149149
endclass
150+
151+
class ibex_cross_pmp_region_mem_access_stream extends riscv_directed_instr_stream;
152+
`uvm_object_utils(ibex_cross_pmp_region_mem_access_stream)
153+
154+
int unsigned pmp_region;
155+
int unsigned region_mask;
156+
int unsigned region_size;
157+
158+
function new (string name = "");
159+
super.new(name);
160+
endfunction
161+
162+
function void calc_region_params();
163+
int unsigned cur_addr = cfg.pmp_cfg.pmp_cfg[pmp_region].addr;
164+
165+
region_size = 8;
166+
region_mask = 32'hfffffffe;
167+
168+
for (int i = 0; i < 29; ++i) begin
169+
if ((cur_addr & 1) == 0) break;
170+
region_size *= 2;
171+
cur_addr >>= 1;
172+
region_mask <<= 1;
173+
end
174+
endfunction
175+
176+
function int unsigned pmp_region_top_addr();
177+
return ((cfg.pmp_cfg.pmp_cfg[pmp_region].addr & region_mask) << 2) + region_size;
178+
endfunction
179+
180+
function int unsigned pmp_region_bottom_addr();
181+
return ((cfg.pmp_cfg.pmp_cfg[pmp_region].addr & region_mask) << 2);
182+
endfunction
183+
184+
function void post_randomize();
185+
int unsigned target_addr;
186+
int unsigned offset;
187+
riscv_pseudo_instr la_instr;
188+
riscv_instr mem_instr;
189+
bit access_at_top;
190+
191+
if (!std::randomize(pmp_region) with {
192+
pmp_region > 1;
193+
pmp_region < cfg.pmp_cfg.pmp_num_regions;
194+
cfg.pmp_cfg.pmp_cfg[pmp_region].a == NAPOT;
195+
})
196+
begin
197+
`uvm_info(`gfn,
198+
{"WARNING: Cannot choose random NAPOT PMP region, skipping cross PMP region access ",
199+
"generation"}, UVM_LOW)
200+
return;
201+
end
202+
203+
initialize_instr_list(2);
204+
205+
calc_region_params();
206+
207+
mem_instr = riscv_instr::get_load_store_instr({LH, LHU, LW, SH, SW});
208+
209+
std::randomize(access_at_top);
210+
211+
if (mem_instr.instr_name inside {LW, SW}) begin
212+
std::randomize(offset) with {offset < 3;offset > 0;};
213+
end else begin
214+
offset = 1;
215+
end
216+
217+
if (access_at_top) begin
218+
target_addr = pmp_region_top_addr() - offset;
219+
end else begin
220+
target_addr = pmp_region_bottom_addr() - offset;
221+
end
222+
223+
la_instr = riscv_pseudo_instr::type_id::create("la_instr");
224+
la_instr.pseudo_instr_name = LA;
225+
la_instr.has_label = 1'b0;
226+
la_instr.atomic = 1'b1;
227+
la_instr.imm_str = $sformatf("0x%x", target_addr);
228+
la_instr.rd = cfg.gpr[1];
229+
230+
randomize_gpr(mem_instr);
231+
mem_instr.has_imm = 0;
232+
mem_instr.imm_str = "0";
233+
mem_instr.rs1 = cfg.gpr[1];
234+
235+
instr_list = {la_instr, mem_instr};
236+
237+
super.post_randomize();
238+
endfunction
239+
endclass

dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,8 @@
844844
+directed_instr_3=riscv_load_store_rand_addr_instr_stream,40
845845
+directed_instr_4=ibex_rand_mseccfg_stream,1
846846
+directed_instr_6=ibex_valid_na4_stream,20
847+
+directed_instr_7=ibex_cross_pmp_region_mem_access_stream,10
848+
+enable_unaligned_load_store=1
847849
sim_opts: >
848850
+is_double_fault_detected_fatal=0
849851
+enable_bad_intg_on_uninit_access=0

0 commit comments

Comments
 (0)