Add unmapped Instructions tests to improve code coverage (#1608)

This commit is contained in:
Jalali 2023-11-08 16:08:19 +01:00 committed by GitHub
parent c67fdff8db
commit 5a7bbafdab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 288 additions and 185 deletions

View file

@ -360,8 +360,8 @@ generated_tests:
DASHBOARD_JOB_TITLE: "Generated Hazard Arithmetic tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Hazard register (RAW) Arithmetic tests using CVA6-DV"
- list_num: 3
DASHBOARD_JOB_TITLE: "Generated CSR tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Random CSR tests using CVA6-DV"
DASHBOARD_JOB_TITLE: "Generated Illegal instruction tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Random Illegal instruction tests using CVA6-DV"
- list_num: 4
DASHBOARD_JOB_TITLE: "Generated MMU tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Random MMU tests using CVA6-DV"

View file

@ -0,0 +1,64 @@
/*
* Copyright 2019 Google LLC
* Copyright 2023 Thales DIS France SAS
*
* 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.
*/
// ---------------------------------------------------------------------------------------------
// This class is used to generate illegal or HINT instructions.
// The illegal instruction will be generated in binary format and mixed with other valid instr.
// The mixed instruction stream will be stored in data section and loaded to instruction pages
// at run time.
// ---------------------------------------------------------------------------------------------
class cva6_illegal_instr_c extends riscv_illegal_instr;
`uvm_object_utils(cva6_illegal_instr_c)
`uvm_object_new
//Overriding the riscv_illegal_instr to ovveride this constraint, and disable kReservedC* constraint
constraint reserved_compressed_instr_c {
solve exception before reserved_c;
solve exception before opcode;
solve reserved_c before instr_bin;
solve reserved_c before c_msb;
solve reserved_c before c_op;
if (XLEN == 32) {
//c.addiw is RV64/RV128 only instruction, the encoding is used for C.JAL for RV32C
reserved_c != kReservedAddiw;
}
if (exception == kReservedCompressedInstr) {
(reserved_c == kIllegalCompressed) -> (instr_bin[15:0] == 0);
(reserved_c == kReservedAddispn) -> ((instr_bin[15:5] == '0) && (c_op == 2'b00));
(reserved_c == kReservedAddiw) -> ((c_msb == 3'b001) && (c_op == 2'b01) &&
(instr_bin[11:7] == 5'b0));
reserved_c != kReservedC0;
reserved_c != kReservedC1;
reserved_c != kReservedC2;
(reserved_c == kReservedAddi16sp) -> ((c_msb == 3'b011) && (c_op == 2'b01) &&
(instr_bin[11:7] == 2) &&
!instr_bin[12] && (instr_bin[6:2] == 0));
(reserved_c == kReservedLui) -> ((c_msb == 3'b011) && (c_op == 2'b01) &&
!instr_bin[12] && (instr_bin[6:2] == 0));
(reserved_c == kReservedJr) -> (instr_bin == 16'b1000_0000_0000_0010);
(reserved_c == kReservedLqsp) -> ((c_msb == 3'b001) && (c_op == 2'b10) &&
(instr_bin[11:7] == 5'b0));
(reserved_c == kReservedLwsp) -> ((c_msb == 3'b010) && (c_op == 2'b10) &&
(instr_bin[11:7] == 5'b0));
(reserved_c == kReservedLdsp) -> ((c_msb == 3'b011) && (c_op == 2'b10) &&
(instr_bin[11:7] == 5'b0));
}
}
endclass

View file

@ -34,6 +34,7 @@ class cva6_instr_base_test_c extends riscv_instr_base_test;
virtual function void build_phase(uvm_phase phase);
override_asm_program_gen();
override_gen_config();
override_illegal_instr();
override_sequence_instr();
super.build_phase(phase);
endfunction
@ -52,6 +53,13 @@ class cva6_instr_base_test_c extends riscv_instr_base_test;
`uvm_info("CVA6_DV", $sformatf("Overrid done "), UVM_LOW)
endfunction
virtual function void override_illegal_instr();
`uvm_info("CVA6_DV", $sformatf("Overriding ..."), UVM_LOW)
uvm_factory::get().set_type_override_by_type(riscv_illegal_instr::get_type(),
cva6_illegal_instr_c::get_type());
`uvm_info("CVA6_DV", $sformatf("Overrid done "), UVM_LOW)
endfunction
virtual function void override_sequence_instr();
`uvm_info("CVA6_DV", $sformatf("Overriding ..."), UVM_LOW)
uvm_factory::get().set_type_override_by_type(riscv_instr_sequence::get_type(),

View file

@ -31,6 +31,7 @@ class cva6_instr_sequence_c extends riscv_instr_sequence;
function new (string name = "");
super.new(name);
unsupported_instr = cva6_unsupported_instr_c::type_id::create("unsupported_instr");
illegal_instr = cva6_illegal_instr_c::type_id::create("illegal_instr");
endfunction
function void insert_unsupported_instr();
@ -53,6 +54,39 @@ class cva6_instr_sequence_c extends riscv_instr_sequence;
end
endfunction
function void insert_illegal_hint_instr();
int bin_instr_cnt;
int idx;
string str;
illegal_instr.init(cfg);
bin_instr_cnt = instr_cnt * cfg.illegal_instr_ratio / 1000;
if (bin_instr_cnt >= 0) begin
`uvm_info(`gfn, $sformatf("Injecting %0d cva6 illegal instructions, ratio %0d/100",
bin_instr_cnt, cfg.illegal_instr_ratio), UVM_LOW)
repeat (bin_instr_cnt) begin
`DV_CHECK_RANDOMIZE_WITH_FATAL(illegal_instr,
exception != kHintInstr;)
str = {indent, $sformatf(".4byte 0x%s # %0s",
illegal_instr.get_bin_str(), illegal_instr.comment)};
idx = $urandom_range(0, instr_string_list.size());
instr_string_list.insert(idx, str);
end
end
bin_instr_cnt = instr_cnt * cfg.hint_instr_ratio / 1000;
if (bin_instr_cnt >= 0) begin
`uvm_info(`gfn, $sformatf("Injecting %0d HINT instructions, ratio %0d/100",
bin_instr_cnt, cfg.illegal_instr_ratio), UVM_LOW)
repeat (bin_instr_cnt) begin
`DV_CHECK_RANDOMIZE_WITH_FATAL(illegal_instr,
exception == kHintInstr;)
str = {indent, $sformatf(".2byte 0x%s # %0s",
illegal_instr.get_bin_str(), illegal_instr.comment)};
idx = $urandom_range(0, instr_string_list.size());
instr_string_list.insert(idx, str);
end
end
endfunction
// Convert the instruction stream to the string format.
// Label is attached to the instruction if available, otherwise attach proper space to make
// the code indent consistent.

View file

@ -19,6 +19,7 @@ package cva6_instr_test_pkg;
`include "cva6_instr_gen_config.sv"
`include "cva6_unsupported_instr.sv"
`include "cva6_illegal_instr.sv"
`include "cva6_reg_hazard_stream.sv"
`include "cva6_instr_sequence.sv"
`include "cva6_asm_program_gen.sv"

View file

@ -138,180 +138,197 @@ class cva6_unsupported_instr_c extends uvm_object;
instr_bin[14:12] == func3;
}
if (has_func2) {
instr_bin[26:25] == func3;
instr_bin[26:25] == func2;
}
}
}
// RV64I instructions
constraint rv64i_instr_c {
if (unsupported_instr == rv64i_instr) {
compressed == 0;
opcode inside {legal_rv64i_opcode};
func3 inside {3'b110, 3'b011, 3'b001, 3'b101, 3'b0};
if (opcode == 7'b0000011) {
func3 inside {3'b110, 3'b011};
}
if (opcode == 7'b0100011) {
func3 == 3'b011;
}
if (opcode == 7'b0011011) {
func3 inside {3'b101, 3'b001, 3'b0};
if (func3 == 3'b101) {
func7 inside {7'b0, 7'b0100000};
}
if (func3 == 3'b001) {
func7 == 7'b0;
}
}
if (opcode == 7'b0111011) {
func3 inside {3'b101, 3'b001, 3'b0};
if (func3 == 3'b0) {
func7 inside {7'b0, 7'b0100000};
}
if (func3 == 3'b001) {
func7 == 7'b0;
}
if (func3 == 3'b101) {
func7 inside {7'b0, 7'b0100000};
}
if (!RV64I inside {supported_isa}) {
if (unsupported_instr == rv64i_instr) {
compressed == 0;
opcode inside {legal_rv64i_opcode};
func3 inside {3'b110, 3'b011, 3'b001, 3'b101, 3'b0};
if (opcode == 7'b0000011) {
func3 inside {3'b110, 3'b011};
}
if (opcode == 7'b0100011) {
func3 == 3'b011;
}
if (opcode == 7'b0011011) {
func3 inside {3'b101, 3'b001, 3'b0};
if (func3 == 3'b101) {
func7 inside {7'b0, 7'b0100000};
}
if (func3 == 3'b001) {
func7 == 7'b0;
}
}
if (opcode == 7'b0111011) {
func3 inside {3'b101, 3'b001, 3'b0};
if (func3 == 3'b0) {
func7 inside {7'b0, 7'b0100000};
}
if (func3 == 3'b001) {
func7 == 7'b0;
}
if (func3 == 3'b101) {
func7 inside {7'b0, 7'b0100000};
}
}
}
}
}
// RV64M instructions
constraint rv64c_instr_c {
if (unsupported_instr == rv64m_instr) {
compressed == 0;
opcode == 7'b0111011;
func3 inside {3'b100, 3'b110, 3'b000, 3'b101, 3'b111};
func7 == 7'b0000001;
constraint rv64m_instr_c {
if (!RV64M inside {supported_isa}) {
if (unsupported_instr == rv64m_instr) {
compressed == 0;
opcode == 7'b0111011;
func3 inside {3'b100, 3'b110, 3'b000, 3'b101, 3'b111};
func7 == 7'b0000001;
}
}
}
// RV64C instructions
constraint rv64m_instr_c {
if (unsupported_instr == rv64c_instr) {
compressed == 1;
c_op != 2'b11;
if (c_op == 2'b0) {
!(c_msb inside {3'b0, 3'b010, 3'b110});
}
if (c_op == 2'b01) {
c_msb == 3'b100;
instr_bin[12:10] inside {3'b0, 3'b001, 3'b111};
if (instr_bin[12:10] != 3'b111) {
instr_bin[6:2] == 5'b0;
}
}
if (c_op == 2'b10) {
!(c_msb inside {3'b100, 3'b010, 3'b110});
if (c_msb == 3'b0) {
instr_bin[6:2] == 5'b0;
instr_bin[12] == 1'b0;
}
}
constraint rv64c_instr_c {
if (!RV64C inside {supported_isa} ||
!RV32FC inside {supported_isa} ||
!RV32DC inside {supported_isa} ||
!RV128C inside {supported_isa}) {
if (unsupported_instr == rv64c_instr) {
compressed == 1;
c_op != 2'b11;
if (c_op == 2'b0) {
!(c_msb inside {3'b0, 3'b010, 3'b100, 3'b110});
}
if (c_op == 2'b01) {
c_msb == 3'b100;
instr_bin[12:10] inside {3'b0, 3'b001, 3'b111};
if (instr_bin[12:10] != 3'b111) {
instr_bin[6:2] == 5'b0;
}
else {
!instr_bin[6:5] inside {2'b10, 2'b11};
}
}
if (c_op == 2'b10) {
!(c_msb inside {3'b100, 3'b010, 3'b110});
if (c_msb == 3'b0) {
instr_bin[6:2] == 5'b0;
instr_bin[12] == 1'b0;
}
}
}
}
}
// RV32FDQ, RV64FDQ instructions
constraint rvfdq_instr_c {
if (unsupported_instr == rvfdq_instr) {
compressed == 0;
opcode inside {legal_rvfdq_opcode};
func7 inside {legal_rvfdq_func7};
if (opcode == 7'b0000111) {
func3 inside {3'b010, 3'b011, 3'b100};
}
if (opcode == 7'b0100111) {
func3 inside {3'b010, 3'b011, 3'b100};
}
if (opcode == 7'b1000011) {
func2 inside {legal_func2};
}
if (opcode == 7'b1000111) {
func2 inside {legal_func2};
}
if (opcode == 7'b1001011) {
func2 inside {legal_func2};
}
if (opcode == 7'b1001111) {
func2 inside {legal_func2};
}
if (opcode == 7'b1010011) {
func3 inside {3'b0, 3'b010, 3'b001};
if (func3 == 3'b0) {
func7 inside {7'b0010000,7'b0010100,7'b1110000,7'b1010000,
7'b1111000,7'b0010001,7'b0010101,7'b1010001,
7'b1110001,7'b1111001,7'b0010011,7'b0010111,
7'b1010011};
if (func7 == 7'b1110000) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1111000) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1110001) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1111001) {
instr_bin[24:20] == 5'b0;
}
}
if (func3 == 3'b001) {
func7 inside {7'b0010000,7'b0010100,7'b1110000,7'b1010000,
7'b0010001,7'b0010101,7'b1010001,7'b1110001,
7'b1010011,7'b1110011,7'b0010011,7'b0010111};
if (func7 == 7'b1110000) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1110001) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1110011) {
instr_bin[24:20] == 5'b0;
}
}
if (func3 == 3'b010) {
func7 inside {7'b0010000,7'b1010000,7'b0010001,7'b1010001,
7'b0010011,7'b1010011};
}
if (func7 == 7'b0101100) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1100000) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
if (func7 == 7'b1101000) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
if (func7 == 7'b0101101) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b0100000) {
instr_bin[24:20] inside {5'b00001, 5'b00011};
}
if (func7 == 7'b0100001) {
instr_bin[24:20] inside {5'b0, 5'b00011};
}
if (func7 == 7'b1100001) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
if (func7 == 7'b1101001) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
if (func7 == 7'b0101111) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b0100011) {
instr_bin[24:20] inside {5'b0, 5'b00001};
}
if (func7 == 7'b1100011) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
if (func7 == 7'b1101011) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
if (!RV32F inside {supported_isa} ||
!RV64F inside {supported_isa} ||
!RV32D inside {supported_isa} ||
!RV64D inside {supported_isa}) {
if (unsupported_instr == rvfdq_instr) {
compressed == 0;
opcode inside {legal_rvfdq_opcode};
func7 inside {legal_rvfdq_func7};
if (opcode == 7'b0000111) {
func3 inside {3'b010, 3'b011, 3'b100};
}
if (opcode == 7'b0100111) {
func3 inside {3'b010, 3'b011, 3'b100};
}
if (opcode == 7'b1000011) {
func2 inside {legal_func2};
}
if (opcode == 7'b1000111) {
func2 inside {legal_func2};
}
if (opcode == 7'b1001011) {
func2 inside {legal_func2};
}
if (opcode == 7'b1001111) {
func2 inside {legal_func2};
}
if (opcode == 7'b1010011) {
func3 inside {3'b0, 3'b010, 3'b001};
if (func3 == 3'b0) {
func7 inside {7'b0010000,7'b0010100,7'b1110000,7'b1010000,
7'b1111000,7'b0010001,7'b0010101,7'b1010001,
7'b1110001,7'b1111001,7'b0010011,7'b0010111,
7'b1010011};
if (func7 == 7'b1110000) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1111000) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1110001) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1111001) {
instr_bin[24:20] == 5'b0;
}
}
if (func3 == 3'b001) {
func7 inside {7'b0010000,7'b0010100,7'b1110000,7'b1010000,
7'b0010001,7'b0010101,7'b1010001,7'b1110001,
7'b1010011,7'b1110011,7'b0010011,7'b0010111};
if (func7 == 7'b1110000) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1110001) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1110011) {
instr_bin[24:20] == 5'b0;
}
}
if (func3 == 3'b010) {
func7 inside {7'b0010000,7'b1010000,7'b0010001,7'b1010001,
7'b0010011,7'b1010011};
}
if (func7 == 7'b0101100) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b1100000) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
if (func7 == 7'b1101000) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
if (func7 == 7'b0101101) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b0100000) {
instr_bin[24:20] inside {5'b00001, 5'b00011};
}
if (func7 == 7'b0100001) {
instr_bin[24:20] inside {5'b0, 5'b00011};
}
if (func7 == 7'b1100001) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
if (func7 == 7'b1101001) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
if (func7 == 7'b0101111) {
instr_bin[24:20] == 5'b0;
}
if (func7 == 7'b0100011) {
instr_bin[24:20] inside {5'b0, 5'b00001};
}
if (func7 == 7'b1100011) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
if (func7 == 7'b1101011) {
instr_bin[24:20] inside {5'b0, 5'b00001, 5'b00010, 5'b00011};
}
}
}
}
}

View file

@ -45,12 +45,10 @@ if [[ "$list_num" = 1 ]];then
TEST_NAME=(
"riscv_arithmetic_basic_test_no_comp"
"riscv_arithmetic_basic_test_bcomp"
"riscv_arithmetic_basic_illegal"
"riscv_arithmetic_basic_test_comp"
"riscv_arithmetic_basic_illegal_hint_test"
"riscv_arithmetic_basic_loop_test"
);
I=(100 100 20 100 20 20);
I=(100 100 100 20);
elif [[ "$list_num" = 2 ]];then
TEST_NAME=(
"riscv_arithmetic_basic_same_reg_test"
@ -60,12 +58,11 @@ elif [[ "$list_num" = 2 ]];then
I=(100 100 100);
elif [[ "$list_num" = 3 ]];then
TEST_NAME=(
"riscv_arithmetic_basic_csr_dummy"
"riscv_arithmetic_basic_Randcsr_test"
"riscv_arithmetic_basic_illegal"
"riscv_arithmetic_basic_illegal_hint_test"
"riscv_arithmetic_basic_ebreak_dret_test"
"riscv_arithmetic_basic_illegal_csr"
);
I=(20 20 20 20);
I=(50 50 50);
elif [[ "$list_num" = 4 ]];then
TEST_NAME=(
"riscv_mmu_stress_hint_test"

View file

@ -76,6 +76,7 @@
+directed_instr_0=riscv_load_store_rand_instr_stream,10
+directed_instr_1=riscv_jal_instr,20
+illegal_instr_ratio=100
+unsupported_instr_ratio=100
+tvec_alignment=8
+enable_zba_extension=1
+enable_zbb_extension=1
@ -208,6 +209,7 @@
+no_csr_instr=1
+enable_x_extension=1
+illegal_instr_ratio=100
+unsupported_instr_ratio=100
+tvec_alignment=8
+enable_zba_extension=1
+enable_zbb_extension=1
@ -345,6 +347,7 @@
+boot_mode=m
+no_csr_instr=1
+illegal_instr_ratio=100
+unsupported_instr_ratio=100
+tvec_alignment=8
+enable_zba_extension=1
+enable_zbb_extension=1
@ -376,28 +379,6 @@
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_illegal_csr
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=5
+directed_instr_0=riscv_int_numeric_corner_stream,4
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=0
+enable_access_invalid_csr_level=1
+disable_compressed_instr=1
+tvec_alignment=8
+enable_zba_extension=1
+enable_zbb_extension=1
+enable_zbc_extension=1
+enable_zbs_extension=1
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_csr_dummy
description: >
Arithmetic instruction test, no load/store/branch instructions
@ -478,6 +459,7 @@
+boot_mode=m
+no_csr_instr=1
+illegal_instr_ratio=100
+unsupported_instr_ratio=100
+hint_instr_ratio=100
+tvec_alignment=8
+enable_zba_extension=1