Skip to content

Commit

Permalink
Merge pull request #164 from XavierAubert/cv32e40p/bsm-update_tb_file…
Browse files Browse the repository at this point in the history
…s_WW06

Add directed tests to improve tb functional coverage holes (uvme_inte…
  • Loading branch information
XavierAubert authored Feb 16, 2024
2 parents e412696 + ef99e85 commit aedcc23
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 0 deletions.
1 change: 1 addition & 0 deletions cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ package cv32e40p_instr_test_pkg;
`include "instr_lib/cv32e40p_pulp_instr_lib.sv"
`include "instr_lib/cv32e40p_pulp_hwloop_instr_lib.sv"
`include "instr_lib/cv32e40p_float_instr_lib.sv"
`include "instr_lib/cv32e40p_instr_for_func_cvg_lib.sv" // directed streams to improve functional coverage holes in v2

// RISCV-DV class override definitions
`include "cv32e40p_rand_instr_stream.sv"
Expand Down
9 changes: 9 additions & 0 deletions cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib.sv
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,15 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream;
end
endfunction: insert_nop_instr

// add wfi
virtual function void insert_wfi_instr();
riscv_instr wfi_instr = new riscv_instr::get_rand_instr(
.include_instr({WFI})
);
instr_list.push_back(wfi_instr);
instr_list[$].comment = {instr_list[$].comment, $sformatf(" [WFI Insertion] ")};
endfunction: insert_wfi_instr

// for overriding direct instr operands with previous instruc rd/fd
virtual function void f_use_prev_rd_on_next_operands(
riscv_instr p_instr=null,
Expand Down
183 changes: 183 additions & 0 deletions cv32e40p/env/corev-dv/instr_lib/cv32e40p_instr_for_func_cvg_lib.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
/*
* Copyright 2023 Dolphin Design
* SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// [Dolphin Design updates]
// This file contains stream classes that use to generate streams that improve functional coverage holes

// this stream is to improve func coverage for in uvme_interrupt_covg_v2 by cycle through all cv_* instructions multiple times for irq and wfi coverage purpose - START
class cv32e40p_cv_instrs_multi_loops_streams extends cv32e40p_float_zfinx_base_instr_stream;

localparam TOTAL_INSTR_C_TYPE = 27;
localparam TOTAL_INSTR_X_TYPE = 304;

bit include_wfi_insn = 0;
int unsigned insert_wfi_cnt = 0;
int unsigned loop_cnt = 0;
int unsigned total_instr = 0;
int unsigned loop_cnt_limit = 0;
int unsigned ignored_instr_cnt = 0;

`uvm_object_utils(cv32e40p_cv_instrs_multi_loops_streams)
`uvm_object_new

constraint ovr_c_others {
num_of_instr_per_stream == total_instr * loop_cnt_limit;
}

// manipulate isns list that need to be covered in this stream
virtual function void init_rand_instr_entry();
reset_rand_instr_entry();

include_group = new[1] ({RV32X});
exclude_instr = new[9] ({CV_START, CV_STARTI, CV_END, CV_ENDI, CV_COUNT, CV_COUNTI, CV_SETUP, CV_SETUPI, CV_ELW}); // TBD: exclude hwloop and cluster insn from wfi cg

// these already covered in all cvg, can be ignored meantime - Start (note: users can modify this to focus on insn list to b ecovered)
ignored_instr_cnt = 4;
exclude_instr = new[exclude_instr.size()+ignored_instr_cnt] ({exclude_instr, CV_MAX, CV_ADDN, CV_AVG_SCI_H, CV_SHUFFLEI3_SCI_B});
// these already covered in all cvg, can be ignored meantime - End

if (include_load_store_base_sp) begin // cover c_[s|l]wsp insn only
include_group = new[include_group.size()+1] ({include_group, RV32C});
// these already covered in all cvg, can be ignored meantime - Start (note: users can modify this to focus on insn list to b ecovered)
exclude_instr = new[exclude_instr.size()+25] ({exclude_instr, C_LW, C_SW, C_ADDI4SPN, C_ADDI, C_LI, C_ADDI16SP, C_LUI,
C_SRLI, C_SRAI, C_ANDI, C_SUB, C_XOR, C_OR, C_AND, C_BEQZ, C_BNEZ, C_SLLI, C_MV, C_EBREAK, C_ADD, C_NOP, C_J,
C_JAL, C_JR, C_JALR});
// these already covered in all cvg, can be ignored meantime - End
end
if (include_load_store_base_sp && !is_zfinx) begin // cover c_[fs|fl]wsp insn only
include_group = new[include_group.size()+1] ({include_group, RV32FC});
exclude_instr = new[exclude_instr.size()+2] ({exclude_instr, C_FLW, C_FSW}); // these already covered in all cvg, can be ignored meantime
end
endfunction : init_rand_instr_entry

virtual function void init_iteration_var();
total_instr = 0; loop_cnt_limit = 0;
if (!include_wfi_insn) total_instr = 2;
else if (!include_load_store_base_sp) total_instr = TOTAL_INSTR_X_TYPE - exclude_instr.size();
else if (include_load_store_base_sp && is_zfinx) total_instr = TOTAL_INSTR_X_TYPE + TOTAL_INSTR_C_TYPE - exclude_instr.size();
else if (include_load_store_base_sp && !is_zfinx) total_instr = TOTAL_INSTR_X_TYPE + TOTAL_INSTR_C_TYPE + TOTAL_INSTR_FC_TYPE - exclude_instr.size();
assert(total_instr > 0);
loop_cnt_limit = (include_wfi_insn) ? 1 : 3;
endfunction: init_iteration_var

virtual function void update_current_instr_arg_list(int idx=0);
if (idx == 0) begin
loop_cnt++; assert (loop_cnt <= loop_cnt_limit);
end
else if (idx != 0 && idx%total_instr == 0) begin
loop_cnt++; assert (loop_cnt <= loop_cnt_limit);
init_rand_instr_entry(); // reinit for next loop
end
endfunction: update_current_instr_arg_list

virtual function void update_next_instr_arg_list(riscv_instr prev_instr=null, int idx=0);
if (exclude_instr.size() > 0) begin
if (use_no_repetitive_instr_per_stream && prev_instr != null) begin
if (!(prev_instr.instr_name inside {exclude_instr}))
exclude_instr = new[exclude_instr.size()+1] ({exclude_instr, prev_instr.instr_name});
// $display("exclude_instr size is %0d", exclude_instr.size());
end
end
else assert(0);
endfunction: update_next_instr_arg_list

function void pre_randomize();
super.pre_randomize();
use_fp_only_for_directed_instr = 0;
en_clr_fflags_af_instr = 0;
include_load_store_base_sp = 1;
use_no_repetitive_instr_per_stream = 1; // expanding exclude_instr per iteration
init_rand_instr_entry();
init_iteration_var();
endfunction: pre_randomize

function void post_randomize();

riscv_instr instr;
riscv_fp_in_x_regs_instr instr_zfinx;
riscv_floating_point_instr instr_f;

// print_stream_setting();
for (int i = 0; i < num_of_instr_per_stream; i++) begin : GEN_N_MANIPULATE_INSTR

if (include_wfi_insn) begin : INTERLEAVE_INSN_WITH_WFI
if (i == 0) begin
`SET_GPR_VALUE(gp_reg_scratch,32'h0000_0008)
// disable global mie
directed_csr_access(.instr_name(CSRRC), .rs1(gp_reg_scratch), .csr(12'h300));
insert_wfi_cnt = $urandom_range(4, 12);
insert_wfi_instr(); insert_wfi_cnt--;
end
else if (i == num_of_instr_per_stream-1) begin
// enable global mie - flush all pending interrupts
directed_csr_access(.instr_name(CSRRS), .rs1(gp_reg_scratch), .csr(12'h300));
insert_nop_instr(1);
end
else if (insert_wfi_cnt == 0) begin
// enable global mie - flush all pending interrupts
directed_csr_access(.instr_name(CSRRS), .rs1(gp_reg_scratch), .csr(12'h300));
insert_nop_instr(1);
// disable global mie
directed_csr_access(.instr_name(CSRRC), .rs1(gp_reg_scratch), .csr(12'h300));
insert_wfi_cnt = $urandom_range(4, 12);
insert_wfi_instr(); insert_wfi_cnt--;
end
else begin
insert_wfi_instr(); insert_wfi_cnt--;
end
end
else begin
/* do nothing */
end

update_current_instr_arg_list(i);
instr = new riscv_instr::get_rand_instr(
.include_instr(include_instr),
.exclude_instr(exclude_instr),
.include_category(include_category),
.exclude_category(exclude_category),
.include_group(include_group),
.exclude_group(exclude_group)
);
update_next_instr_arg_list(instr, i);

assert(instr.group inside {RV32C, RV32FC, RV32X}); // these are the intended groups in this stream
randomize_gpr(instr);
if (instr.instr_name inside {`STORE_INSTR_LIST, `FP_STORE_INSTR_LIST})
store_instr_gpr_handling(instr);

instr.comment = $sformatf(" Inserted %0s - idx[%0d]", get_name(), i);
instr_list.push_back(instr);
end // num_of_instr_per_stream

endfunction: post_randomize

endclass: cv32e40p_cv_instrs_multi_loops_streams

class cv32e40p_cv_instrs_w_wfi_multi_loops_streams extends cv32e40p_cv_instrs_multi_loops_streams;

`uvm_object_utils(cv32e40p_cv_instrs_w_wfi_multi_loops_streams)
`uvm_object_new

function void pre_randomize();
include_wfi_insn = 1;
super.pre_randomize();
endfunction: pre_randomize

endclass: cv32e40p_cv_instrs_w_wfi_multi_loops_streams
// this stream is to improve func coverage for in uvme_interrupt_covg_v2 by cycle through all cv_* instructions multiple times for irq and wfi coverage purpose - END

29 changes: 29 additions & 0 deletions cv32e40p/regress/cv32e40pv2_for_func_cvg_improvement.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2023 Dolphin Design
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1

# Header
name: cv32e40pv2_for_func_cvg_improvement
description: regression for CV32E40Pv2, focused on improving the functional coverage holes

# List of builds
# cfg is set to pulp by default but can be overriden by arg command to any cfg.
builds:
clean_fw:
cmd: make clean-bsp clean_test_programs
dir: cv32e40p/sim/uvmt
clean_corev-dv:
cmd: make clean_riscv-dv clone_riscv-dv
dir: cv32e40p/sim/uvmt
uvmt_cv32e40p:
cmd: make comp comp_corev-dv
dir: cv32e40p/sim/uvmt
cfg: pulp

# List of tests
tests:
corev_directed_for_interrupt_covg_test:
build: uvmt_cv32e40p
description: This test is to improve func coverage holes in uvme_interrupt_covg_v2
dir: cv32e40p/sim/uvmt
cmd: make gen_corev-dv test COREV=YES TEST=corev_directed_for_interrupt_covg_test CFG_PLUSARGS="+UVM_TIMEOUT=30000000"
num: 5
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
corev_*.*
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: corev_directed_for_interrupt_covg_test
uvm_test: $(CV_CORE_LC)_instr_base_test
description: >
This test is to improve func coverage holes in uvme_interrupt_covg_v2
plusargs: >
+instr_cnt=1000
+num_of_sub_program=0
+directed_instr_0=cv32e40p_cv_instrs_w_wfi_multi_loops_streams,1
+directed_instr_1=cv32e40p_cv_instrs_multi_loops_streams,3000
+enable_interrupt=1
+enable_fast_interrupt_handler=1
+no_fence=0
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=0
+no_wfi=1
+no_dret=1
+fix_sp=1
+randomize_csr=1
+test_override_riscv_instr_stream=1
+test_override_riscv_instr_sequence=1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright 2023 Dolphin Design
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1

# Test definition YAML for random pulp instr test
name: corev_directed_for_interrupt_covg_test
uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c
description: >
This test is to improve func coverage holes in uvme_interrupt_covg_v2
plusargs: >
+gen_irq_noise

0 comments on commit aedcc23

Please sign in to comment.