diff --git a/bin/cv_regress b/bin/cv_regress index 8069f539c7..12ca026d5a 100755 --- a/bin/cv_regress +++ b/bin/cv_regress @@ -154,14 +154,24 @@ def read_file(args, file): if not test.builds and test.build: test.builds = [ test.build ] + if args.force_test_cfg: + test.test_cfg = args.force_test_cfg + if args.add_test_cfg: + arg_list = [test.test_cfg if hasattr(test, 'test_cfg') else "", args.add_test_cfg] + test.test_cfg = ",".join(a for a in arg_list if a) + # Determine if a test is valid, skip for compliance tests # Since it is not possible to determine apriori if a compliance test is valid if not 'compliance' in test.cmd: check_valid_test(args.project, test.testname) # Determine if a test is indexed for setting test iterations - if args.num: - test.num = int(args.num) + # if num is not specified in the yaml, it can be overriden by args.num or set to 1 to avoid issues + # else, if it is not set to 1 (unique), it can be overriden by args.num if argument is defined + if test.num == None: + test.num = int(args.num or 1) + elif test.num != 1: + test.num = int(args.num or test.num) regression.add_test(test) @@ -193,6 +203,8 @@ parser.add_argument('--results', help='Set a non-standard results directory') parser.add_argument('-s', '--simulator', help='Select simulator', choices=VALID_SIMULATORS, default=DEFAULT_SIMULATOR) parser.add_argument('-c', '--cov', help='Enable coverage', action='store_true') parser.add_argument('--cfg', default=None, help='Override configuration for all builds and tests in regression') +parser.add_argument('--force_test_cfg', default=None, help='Override test_cfg file(s) for all builds and tests in regression. Each cfg file should be separated by a comma') +parser.add_argument('--add_test_cfg', default=None, help='Additional test_cfg file(s) for all builds and tests in regression. Each cfg file should be separated by a comma') parser.add_argument('--iss', default=None, help='Force USE_ISS flag to each test run') parser.add_argument('--parallel', default=DEFAULT_PARALLEL, help='For VSIF only, set number of parallel jobs') parser.add_argument('-m', '--metrics', help='Select Metrics waves output', action='store_true') diff --git a/bin/lib/cv_regression.py b/bin/lib/cv_regression.py index f0bee78731..076175f676 100644 --- a/bin/lib/cv_regression.py +++ b/bin/lib/cv_regression.py @@ -76,7 +76,8 @@ def __init__(self, **kwargs): self.simulation_passed = DEFAULT_SIMULATION_PASSED self.simulation_failed = DEFAULT_SIMULATION_FAILED self.iss = DEFAULT_ISS - self.num = 1 + # value is handled in main cv_regress script + self.num = None self.builds = [] for k, v in kwargs.items(): diff --git a/bin/templates/regress_rmdb.j2 b/bin/templates/regress_rmdb.j2 index 56e0c15484..c2ab88850e 100644 --- a/bin/templates/regress_rmdb.j2 +++ b/bin/templates/regress_rmdb.j2 @@ -4,12 +4,11 @@ {% import 'regress_macros.j2' as regress_macros -%} - - + proc getUCDBFilename {base_name test_cfg} { if {[string trim $test_cfg] != ""} { - return [concat $base_name "-" $test_cfg ] + return ${base_name}_${test_cfg} } return $base_name } @@ -37,6 +36,24 @@ } + + proc getTestCfgName { test_config_from_cmd } { + return [join [lsort -unique [split $test_config_from_cmd ",+ "]] "__"] + } + + + + proc getTestName {testname config test_config seed} { + if {$test_config == ""} { + return [format "%s" ${testname}__${config}__$seed] + } else { + set test_list_name [getTestCfgName $test_config] + return [format "%s" ${testname}__${test_list_name}__${config}__$seed] + } + + } + + {{results_path}}/{{simulator}}_results @@ -45,16 +62,21 @@ {% for r in regressions %} {{r.name}} {% endfor %} - report {% for r in regressions %} + {% for build in r.get_builds() %} {{build.name}} +{% endfor %} +{% for build in r.get_builds() %} +{% if coverage != false %} + cov_report_{{build.name}} +{% endif %} {% endfor %} @@ -65,6 +87,7 @@ + {% for build in r.get_builds() %} @@ -81,22 +104,28 @@ {% endfor %} + echo "BUILD RUNCMD: {{build.cmd}} CV_CORE={{project}} CFG={{build.cfg}} {{toolchain|upper}}=1 SIMULATOR={{build.simulator}} USE_ISS={{regress_macros.yesorno(build.iss)}} COV={{regress_macros.yesorno(build.cov)}} {{regress_macros.cv_results(results)}} {{makeargs}}" cd {{build.abs_dir}} && {{build.cmd}} CV_CORE={{project}} CFG={{build.cfg}} {{toolchain|upper}}=1 SIMULATOR={{build.simulator}} USE_ISS={{regress_macros.yesorno(build.iss)}} COV={{regress_macros.yesorno(build.cov)}} {{regress_macros.cv_results(results)}} {{makeargs}} - {% endfor %} + + + {% for k,t in unique_tests.items() %} - + - [getParameterByPriority "{{config}}" "{{t.cfg}}" "(%build_config:%)"] - [getParameterByPriority "" "{{t.test_cfg}}" "(%build_test_cfg:%)"] - [getParameterByPriorityYesOrNo "{{iss}}" "{{t.iss}}" "(%build_iss:%)"] - [getParameterByPriorityYesOrNo "{{coverage}}" "{{t.cov}}" "(%build_cov:%)"] - [file join "(%results_sim_path%)" "(%t_cfg%)" "{{t.testname}}" "(%t_test_cfg:%)" "(%ITERATION%)"] - [getUCDBFilename "{{t.testname}}" "(%t_test_cfg:%)"] + [getParameterByPriority "{{config}}" "{{t.cfg}}" "(%build_config:%)"] + [getParameterByPriority "" "{{t.test_cfg}}" "(%build_test_cfg:%)"] + [getTestCfgName (%t_test_cfg:%)] + [getParameterByPriorityYesOrNo "{{iss}}" "{{t.iss}}" "(%build_iss:%)"] + [getParameterByPriorityYesOrNo "{{coverage}}" "{{t.cov}}" "(%build_cov:%)"] + [GetRandomValues {{t.num}}] + [file join "(%results_sim_path%)" "(%t_cfg%)" "{{t.testname}}" "(%t_test_cfg_name:%)" "(%ITERATION%)"] + [getTestName "{{t.testname}}" "(%t_cfg%)" "(%t_test_cfg_name:%)" "(%ITERATION%)"] + [getUCDBFilename "{{t.testname}}" "(%t_test_cfg_name:%)"] {% if coverage != false %} (%ucdb_path%)/(%ucdb_basename%).ucdb {% endif %} @@ -108,38 +137,48 @@ {% endif %} - cd {{t.abs_dir}} && {{t.cmd}} CHECK_SIM_RESULT={{regress_macros.yesorno(check_sim_results)}} CHECK_SIM_LOG=(%log_file%) COMP=0 CV_CORE={{project}} {{toolchain|upper}}=1 CFG=(%t_cfg%) TEST_CFG_FILE=(%t_test_cfg:%) SIMULATOR={{t.simulator}} USE_ISS=(%t_iss:%) COV=(%t_cov:%) RUN_INDEX=(%ITERATION%) GEN_START_INDEX=(%ITERATION%) SEED=random {{regress_macros.cv_results(results)}} {{makeargs}} {{t.makearg}} + echo " TEST RUNCMD: {{t.cmd}} CHECK_SIM_RESULT={{regress_macros.yesorno(check_sim_results)}} COMP=0 CV_CORE={{project}} {{toolchain|upper}}=1 CFG=(%t_cfg%) TEST_CFG_FILE=(%t_test_cfg:%) SIMULATOR={{t.simulator}} USE_ISS=(%t_iss:%) COV=(%t_cov:%) RUN_INDEX=(%ITERATION%) GEN_START_INDEX=(%ITERATION%) SEED=(%ITERATION%) {{regress_macros.cv_results(results)}} {{makeargs}} {{t.makearg}}" + echo " logfile: (%log_file%)" + cd {{t.abs_dir}} && {{t.cmd}} CHECK_SIM_RESULT={{regress_macros.yesorno(check_sim_results)}} CHECK_SIM_LOG=(%log_file%) COMP=0 CV_CORE={{project}} {{toolchain|upper}}=1 CFG=(%t_cfg%) TEST_CFG_FILE=(%t_test_cfg:%) SIMULATOR={{t.simulator}} USE_ISS=(%t_iss:%) COV=(%t_cov:%) RUN_INDEX=(%ITERATION%) GEN_START_INDEX=(%ITERATION%) SEED=(%ITERATION%) {{regress_macros.cv_results(results)}} {{makeargs}} {{t.makearg}} {% endfor %} + {% endfor %} + - - + + +{% for r in regressions %} +{% for build in r.get_builds() %} + - (%results_sim_path%)/merged/merged.ucdb + (%results_sim_path%)/{{build.cfg}}/merged/merged.ucdb {% if coverage != false %} - cd {{results_path}} && make cov_merge SIMULATOR={{simulator}} + cd {{results_path}} && make cov_merge CFG={{build.cfg}} SIMULATOR={{simulator}} {% endif %} - html_report + html_report_{{build.name}} - vrun -vrmdata (%DATADIR%) -status -full -html -htmldir (%DATADIR%)/vrun + vrun -vrmdata (%DATADIR%) -status -testname -full -html -htmldir (%DATADIR%)/vrun - - - - if {[file exists (%merged_file%)]} {vcover report -annotate -testdetails -details -html (%merged_file%) -output [file join {{results_path}} cov_html_summary]} + + + if {[file exists (%merged_file%)]} {vcover report -annotate -testdetails -details -html (%merged_file%) -output (%results_sim_path%)/{{build.cfg}}/cov_html_summary} - + + +{% endfor %} +{% endfor %} + diff --git a/cv32e40p/env/corev-dv/custom/isa/cv32e40p_riscv_compressed_instr.sv b/cv32e40p/env/corev-dv/custom/isa/cv32e40p_riscv_compressed_instr.sv new file mode 100644 index 0000000000..94da416622 --- /dev/null +++ b/cv32e40p/env/corev-dv/custom/isa/cv32e40p_riscv_compressed_instr.sv @@ -0,0 +1,187 @@ +/* + * Copyright 2020 Google LLC + * + * 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. + * + * + * Copyright 2023 OpenHW Group + * Copyright 2023 Dolphin Design + * + * SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + */ + +class cv32e40p_riscv_compressed_instr extends riscv_compressed_instr; + + rand riscv_fpr_t fs1; + rand riscv_fpr_t fs2; + rand riscv_fpr_t fd; + rand bit[4:0] reg_idx_fs2; //FIXME : dd-vaibhavjain + rand bit[4:0] reg_idx_fd; //FIXME : dd-vaibhavjain + + //FIXME: dd-vaibhavjain. Remove after toolchain fix + constraint rv32fc_reg_idx_temp_c { + if (instr_name == C_FLW) { + reg_idx_fd inside {[8:15]}; + } + if (instr_name == C_FSW) { + reg_idx_fs2 inside {[8:15]}; + } + } + + constraint rvc_csr_c { + // Registers specified by the three-bit rs1’, rs2’, and rd’ + if (format inside {CIW_FORMAT, CL_FORMAT, CS_FORMAT, CB_FORMAT, CA_FORMAT}) { + if (has_rs1) { + rs1 inside {[S0:A5]}; + fs1 inside {[S0:A5]}; + } + if (has_rs2) { + rs2 inside {[S0:A5]}; + fs2 inside {[S0:A5]}; + } + if (has_rd) { + rd inside {[S0:A5]}; + fd inside {[S0:A5]}; + } + } + // C_ADDI16SP is only valid when rd == SP + if (instr_name == C_ADDI16SP) { + rd == SP; + } + if (instr_name inside {C_JR, C_JALR}) { + rs2 == ZERO; + rs1 != ZERO; + } + } + + `uvm_object_utils(cv32e40p_riscv_compressed_instr) + + function new(string name = ""); + super.new(name); + fs1 = FS0; + fs2 = FS0; + fd = FS0; + endfunction : new + + virtual function void set_imm_len(); + if (format inside {CI_FORMAT, CSS_FORMAT}) begin + imm_len = 6; + end else if (format inside {CL_FORMAT, CS_FORMAT}) begin + imm_len = 5; + end else if (format inside {CJ_FORMAT}) begin + imm_len = 11; + end else if (format inside {CB_FORMAT}) begin + if (instr_name == C_ANDI) begin + imm_len = 6; + end else begin + imm_len = 7; + end + end else if (format inside {CB_FORMAT, CIW_FORMAT}) begin + imm_len = 8; + end + if (instr_name inside {C_SQ, C_LQ, C_LQSP, C_SQSP, C_ADDI16SP}) begin + imm_align = 4; + end else if (instr_name inside {C_SD, C_LD, C_LDSP, C_SDSP}) begin + imm_align = 3; + end else if (instr_name inside {C_SW, C_LW, C_LWSP, C_SWSP, C_ADDI4SPN, C_FSW, C_FLW, C_FLWSP, C_FSWSP}) begin + imm_align = 2; + end else if (instr_name inside {C_LUI}) begin + imm_align = 12; + end else if (instr_name inside {C_J, C_JAL, C_BNEZ, C_BEQZ}) begin + imm_align = 1; + end + endfunction : set_imm_len + + // Convert the instruction to assembly code + virtual function string convert2asm(string prefix = ""); + string asm_str; + asm_str = format_string(get_instr_name(), MAX_INSTR_STR_LEN); + + std::randomize(reg_idx_fs2) with { if (instr_name == C_FSW) { + reg_idx_fs2 inside {[8:15]}; + } + }; //FIXME : dd-vaibhavjain + + std::randomize(reg_idx_fd) with { if (instr_name == C_FLW) { + reg_idx_fd inside {[8:15]}; + } + }; //FIXME : dd-vaibhavjain + + + if (category != SYSTEM) begin + case(format) + CI_FORMAT, CIW_FORMAT: + if (instr_name == C_NOP) + asm_str = "c.nop"; + else if (instr_name == C_ADDI16SP) + asm_str = $sformatf("%0ssp, %0s", asm_str, get_imm()); + else if (instr_name == C_ADDI4SPN) + asm_str = $sformatf("%0s%0s, sp, %0s", asm_str, rd.name(), get_imm()); + else if (instr_name inside {C_LDSP, C_LWSP, C_LQSP}) + asm_str = $sformatf("%0s%0s, %0s(sp)", asm_str, rd.name(), get_imm()); + else if (instr_name inside {C_FLWSP}) + //asm_str = $sformatf("%0s%0s, %0s(sp)", asm_str, fd.name(), get_imm()); + asm_str = $sformatf("%0s f%0d, %0s(sp)", asm_str, reg_idx_fd, get_imm()); //FIXME : dd-vaibhavjain. revert temp wrd after toolchain fix + else + asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), get_imm()); + CL_FORMAT: + if (instr_name == C_FLW) + //asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, fd.name(), get_imm(), rs1.name()); + asm_str = $sformatf("%0s f%0d, %0s(%0s)", asm_str, reg_idx_fd, get_imm(), rs1.name()); //FIXME : dd-vaibhavjain. revert temp wrd after toolchain fix + else + asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, rd.name(), get_imm(), rs1.name()); + CS_FORMAT: + if (category == STORE) + if (instr_name == C_FSW) + //asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, fs2.name(), get_imm(), rs1.name()); + asm_str = $sformatf("%0s f%0d, %0s(%0s)", asm_str, reg_idx_fs2, get_imm(), rs1.name()); //FIXME : dd-vaibhavjain. revert temp wrd after toolchain fix + else + asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, rs2.name(), get_imm(), rs1.name()); + else + asm_str = $sformatf("%0s%0s, %0s", asm_str, rs1.name(), rs2.name()); + CA_FORMAT: + asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), rs2.name()); + CB_FORMAT: + asm_str = $sformatf("%0s%0s, %0s", asm_str, rs1.name(), get_imm()); + CSS_FORMAT: + if (category == STORE) + if (instr_name == C_FSWSP) + //asm_str = $sformatf("%0s%0s, %0s(sp)", asm_str, fs2.name(), get_imm()); + asm_str = $sformatf("%0s f%0d, %0s(sp)", asm_str, reg_idx_fs2, get_imm()); //FIXME : dd-vaibhavjain. revert temp wrd after toolchain fix + else + asm_str = $sformatf("%0s%0s, %0s(sp)", asm_str, rs2.name(), get_imm()); + else + asm_str = $sformatf("%0s%0s, %0s", asm_str, rs2.name(), get_imm()); + CR_FORMAT: + if (instr_name inside {C_JR, C_JALR}) begin + asm_str = $sformatf("%0s%0s", asm_str, rs1.name()); + end else begin + asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), rs2.name()); + end + CJ_FORMAT: + asm_str = $sformatf("%0s%0s", asm_str, get_imm()); + default: `uvm_info(`gfn, $sformatf("Unsupported format %0s", format.name()), UVM_LOW) + endcase + end else begin + // For EBREAK,C.EBREAK, making sure pc+4 is a valid instruction boundary + // This is needed to resume execution from epc+4 after ebreak handling + if (instr_name == C_EBREAK) begin + asm_str = "c.ebreak;c.nop;"; + end + end + if (comment != "") + asm_str = {asm_str, " #",comment}; + return asm_str.tolower(); + endfunction : convert2asm + +endclass : cv32e40p_riscv_compressed_instr diff --git a/cv32e40p/env/corev-dv/custom/isa/riscv_floating_point_instr.sv b/cv32e40p/env/corev-dv/custom/isa/riscv_floating_point_instr.sv index 77f7a95336..a10b168f10 100644 --- a/cv32e40p/env/corev-dv/custom/isa/riscv_floating_point_instr.sv +++ b/cv32e40p/env/corev-dv/custom/isa/riscv_floating_point_instr.sv @@ -76,7 +76,7 @@ class riscv_floating_point_instr extends riscv_instr; FMV_D_X, FMV_X_D, FCLASS_S, FCLASS_D, FCVT_D_S, FCVT_D_W, FCVT_D_WU, FSGNJ_S, FSGNJN_S, FSGNJX_S, FSGNJ_D, FSGNJN_D, FSGNJX_D})) begin - asm_str = {asm_str, ", ", rm.name()}; + if (rm != DYN) asm_str = {asm_str, ", ", rm.name()}; end if(comment != "") asm_str = {asm_str, " #",comment}; diff --git a/cv32e40p/env/corev-dv/custom/isa/riscv_fp_in_x_regs_instr.sv b/cv32e40p/env/corev-dv/custom/isa/riscv_fp_in_x_regs_instr.sv index 23a4ab0b33..079b051f11 100644 --- a/cv32e40p/env/corev-dv/custom/isa/riscv_fp_in_x_regs_instr.sv +++ b/cv32e40p/env/corev-dv/custom/isa/riscv_fp_in_x_regs_instr.sv @@ -56,7 +56,7 @@ class riscv_fp_in_x_regs_instr extends riscv_instr; !(instr_name inside {FMIN_S, FMAX_S, FMIN_D, FMAX_D, FCLASS_S, FCLASS_D, FCVT_D_S, FCVT_D_W, FCVT_D_WU, FSGNJ_S, FSGNJN_S, FSGNJX_S, FSGNJ_D, FSGNJN_D, FSGNJX_D})) begin - asm_str = {asm_str, ", ", rm.name()}; + if (rm != DYN) asm_str = {asm_str, ", ", rm.name()}; end if(comment != "") asm_str = {asm_str, " #",comment}; diff --git a/cv32e40p/env/corev-dv/custom/isa/riscv_instr.sv b/cv32e40p/env/corev-dv/custom/isa/riscv_instr.sv index 75423f6413..ec7eb290be 100644 --- a/cv32e40p/env/corev-dv/custom/isa/riscv_instr.sv +++ b/cv32e40p/env/corev-dv/custom/isa/riscv_instr.sv @@ -126,7 +126,7 @@ class riscv_instr extends uvm_object; !(cfg.disable_compressed_instr && (instr_inst.group inside {RV32C, RV64C, RV32DC, RV32FC, RV128C})) && !(!cfg.enable_floating_point && - (instr_inst.group inside {RV32F, RV64F, RV32D, RV64D})) && + (instr_inst.group inside {RV32F, RV64F, RV32D, RV64D, RV32DC, RV32FC})) && !(!cfg.enable_vector_extension && (instr_inst.group inside {RVV})) && !(cfg.vector_instr_only && diff --git a/cv32e40p/env/corev-dv/custom/riscv_defines.svh b/cv32e40p/env/corev-dv/custom/riscv_defines.svh index 3b0baefe5c..efb1da7833 100644 --- a/cv32e40p/env/corev-dv/custom/riscv_defines.svh +++ b/cv32e40p/env/corev-dv/custom/riscv_defines.svh @@ -91,7 +91,7 @@ // Floating point compressed instruction `define DEFINE_FC_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp = IMM) \ - class riscv_``instr_n``_instr extends riscv_compressed_instr; \ + class riscv_``instr_n``_instr extends cv32e40p_riscv_compressed_instr; \ `INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp) // Vector arithmetic instruction diff --git a/cv32e40p/env/corev-dv/custom/riscv_instr_gen_config.sv b/cv32e40p/env/corev-dv/custom/riscv_instr_gen_config.sv index 63684bca40..514c86a0fb 100644 --- a/cv32e40p/env/corev-dv/custom/riscv_instr_gen_config.sv +++ b/cv32e40p/env/corev-dv/custom/riscv_instr_gen_config.sv @@ -467,6 +467,10 @@ class riscv_instr_gen_config extends uvm_object; } } + constraint fcsr_rm_c { + fcsr_rm != DYN; + } + `uvm_object_utils_begin(riscv_instr_gen_config) `uvm_field_int(main_program_instr_cnt, UVM_DEFAULT) `uvm_field_sarray_int(sub_program_instr_cnt, UVM_DEFAULT) diff --git a/cv32e40p/env/corev-dv/custom/riscv_instr_pkg.sv b/cv32e40p/env/corev-dv/custom/riscv_instr_pkg.sv index 0ad7ab7049..e15d063cf3 100644 --- a/cv32e40p/env/corev-dv/custom/riscv_instr_pkg.sv +++ b/cv32e40p/env/corev-dv/custom/riscv_instr_pkg.sv @@ -56,7 +56,8 @@ package riscv_instr_pkg; RTZ = 3'b001, RDN = 3'b010, RUP = 3'b011, - RMM = 3'b100 + RMM = 3'b100, + DYN = 3'b111 } f_rounding_mode_t; typedef enum bit [1:0] { @@ -1197,7 +1198,7 @@ package riscv_instr_pkg; parameter int DATA_WIDTH = 32; // Parameters for output assembly program formatting - parameter int MAX_INSTR_STR_LEN = 13; + parameter int MAX_INSTR_STR_LEN = 21; parameter int MAX_PULP_INSTR_STR_LEN = 20; parameter int LABEL_STR_LEN = 18; @@ -1413,6 +1414,7 @@ package riscv_instr_pkg; `include "isa/riscv_fp_in_x_regs_instr.sv" `include "isa/riscv_vector_instr.sv" `include "isa/riscv_compressed_instr.sv" + `include "isa/cv32e40p_riscv_compressed_instr.sv" `include "isa/rv32a_instr.sv" `include "isa/rv32c_instr.sv" `include "isa/rv32dc_instr.sv" diff --git a/cv32e40p/env/corev-dv/cv32e40p_asm_program_gen.sv b/cv32e40p/env/corev-dv/cv32e40p_asm_program_gen.sv index 3712578f08..c5d6b4049a 100644 --- a/cv32e40p/env/corev-dv/cv32e40p_asm_program_gen.sv +++ b/cv32e40p/env/corev-dv/cv32e40p_asm_program_gen.sv @@ -21,9 +21,18 @@ // CV32E40P CORE-V assembly program generator - extension of the RISC-V assembly program generator. // // Overrides: +// - gen_trap_handler_section() +// - gen_interrupt_vector_table() // - gen_program_header() // - gen_test_done() // - get_directed_instr_stream() +// - init_gpr() +// - init_floating_point_gpr() +// - gen_ebreak_handler() +// - gen_illegal_instr_handler() +// - gen_instr_fault_handler() +// - gen_load_fault_handler() +// - gen_store_fault_handler() //----------------------------------------------------------------------------------------- class cv32e40p_asm_program_gen extends corev_asm_program_gen; @@ -34,6 +43,116 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen; super.new(name); endfunction + // Override the gen_trap_handler_section function from riscv_asm_program_gen.sv + // Replace push_gpr_to_kernel_stack with push_regfile_to_kernel_stack + virtual function void gen_trap_handler_section(int hart, + string mode, + privileged_reg_t cause, privileged_reg_t tvec, + privileged_reg_t tval, privileged_reg_t epc, + privileged_reg_t scratch, privileged_reg_t status, + privileged_reg_t ie, privileged_reg_t ip); + bit is_interrupt = 'b1; + string tvec_name; + string instr[$]; + cv32e40p_instr_gen_config corev_cfg; + + `DV_CHECK_FATAL($cast(corev_cfg, cfg), "Could not cast cfg into corev_cfg") + + if (cfg.mtvec_mode == VECTORED) begin + gen_interrupt_vector_table(hart, mode, status, cause, ie, ip, scratch, instr); + end else begin + // Push user mode GPR to kernel stack before executing exception handling, this is to avoid + // exception handling routine modify user program state unexpectedly + + // Replace push_gpr_to_kernel_stack with push_regfile_to_kernel_stack + //push_gpr_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr); + push_regfile_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg); + + // Checking xStatus can be optional if ISS (like spike) has different implementation of + // certain fields compared with the RTL processor. + if (cfg.check_xstatus) begin + instr = {instr, $sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], status, status.name())}; + end + instr = {instr, + // Use scratch CSR to save a GPR value + // Check if the exception is caused by an interrupt, if yes, jump to interrupt + // handler Interrupt is indicated by xCause[XLEN-1] + $sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], cause, cause.name()), + $sformatf("srli x%0d, x%0d, %0d", cfg.gpr[0], cfg.gpr[0], XLEN-1), + $sformatf("bne x%0d, x0, %0s%0smode_intr_handler", + cfg.gpr[0], hart_prefix(hart), mode)}; + end + // The trap handler will occupy one 4KB page, it will be allocated one entry in the page table + // with a specific privileged mode. + if (SATP_MODE != BARE) begin + instr_stream.push_back(".align 12"); + end else begin + instr_stream.push_back($sformatf(".align %d", cfg.tvec_alignment)); + end + tvec_name = tvec.name(); + gen_section(get_label($sformatf("%0s_handler", tvec_name.tolower()), hart), instr); + // Exception handler + instr = {}; + if (cfg.mtvec_mode == VECTORED) begin + // Replace push_gpr_to_kernel_stack with push_regfile_to_kernel_stack + //push_gpr_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr); + push_regfile_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg); + end + gen_signature_handshake(instr, CORE_STATUS, HANDLING_EXCEPTION); + instr = {instr, + // The trap is caused by an exception, read back xCAUSE, xEPC to see if these + // CSR values are set properly. The checking is done by comparing against the log + // generated by ISA simulator (spike). + $sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], epc, epc.name()), + $sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], cause, cause.name()), + // Breakpoint + $sformatf("li x%0d, 0x%0x # BREAKPOINT", cfg.gpr[1], BREAKPOINT), + $sformatf("beq x%0d, x%0d, %0sebreak_handler", + cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)), + // Check if it's an ECALL exception. Jump to ECALL exception handler + $sformatf("li x%0d, 0x%0x # ECALL_UMODE", cfg.gpr[1], ECALL_UMODE), + $sformatf("beq x%0d, x%0d, %0secall_handler", + cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)), + $sformatf("li x%0d, 0x%0x # ECALL_SMODE", cfg.gpr[1], ECALL_SMODE), + $sformatf("beq x%0d, x%0d, %0secall_handler", + cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)), + $sformatf("li x%0d, 0x%0x # ECALL_MMODE", cfg.gpr[1], ECALL_MMODE), + $sformatf("beq x%0d, x%0d, %0secall_handler", + cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)), + // Page table fault or access fault conditions + $sformatf("li x%0d, 0x%0x", cfg.gpr[1], INSTRUCTION_ACCESS_FAULT), + $sformatf("beq x%0d, x%0d, %0sinstr_fault_handler", + cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)), + $sformatf("li x%0d, 0x%0x", cfg.gpr[1], LOAD_ACCESS_FAULT), + $sformatf("beq x%0d, x%0d, %0sload_fault_handler", + cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)), + $sformatf("li x%0d, 0x%0x", cfg.gpr[1], STORE_AMO_ACCESS_FAULT), + $sformatf("beq x%0d, x%0d, %0sstore_fault_handler", + cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)), + $sformatf("li x%0d, 0x%0x", cfg.gpr[1], INSTRUCTION_PAGE_FAULT), + $sformatf("beq x%0d, x%0d, %0spt_fault_handler", + cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)), + $sformatf("li x%0d, 0x%0x", cfg.gpr[1], LOAD_PAGE_FAULT), + $sformatf("beq x%0d, x%0d, %0spt_fault_handler", + cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)), + $sformatf("li x%0d, 0x%0x", cfg.gpr[1], STORE_AMO_PAGE_FAULT), + $sformatf("beq x%0d, x%0d, %0spt_fault_handler", + cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)), + // Illegal instruction exception + $sformatf("li x%0d, 0x%0x # ILLEGAL_INSTRUCTION", cfg.gpr[1], ILLEGAL_INSTRUCTION), + $sformatf("beq x%0d, x%0d, %0sillegal_instr_handler", + cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)), + // Skip checking tval for illegal instruction as it's implementation specific + $sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[1], tval, tval.name()), + // use JALR to jump to test_done. + $sformatf("1: la x%0d, test_done", cfg.scratch_reg), + $sformatf("jalr x1, x%0d, 0", cfg.scratch_reg) + }; + gen_section(get_label($sformatf("%0smode_exception_handler", mode), hart), instr); + endfunction + + //Override gen_interrupt_vector_table + //Replace push_gpr_to_kernel_stack with push_regfile_to_kernel_stack virtual function void gen_interrupt_vector_table(int hart, string mode, privileged_reg_t status, @@ -75,7 +194,11 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen; end else begin // Standard full-stack-save interrupt handler - push_gpr_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, intr_handler); + + // Replace push_gpr_to_kernel_stack with push_regfile_to_kernel_stack + //push_gpr_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, intr_handler); + push_regfile_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, intr_handler, corev_cfg); + gen_signature_handshake(.instr(intr_handler), .signature_type(CORE_STATUS), .core_status(HANDLING_IRQ)); intr_handler = {intr_handler, @@ -120,12 +243,16 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen; // Override from risc-dv: // 1. Remove MIP read, since interrupts are auto-cleared, mip will not track through the ISS // to GPR properly with autoclear + // 2. Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack virtual function void gen_interrupt_handler_section(privileged_mode_t mode, int hart); string mode_prefix; string ls_unit; privileged_reg_t status, ip, ie, scratch; string interrupt_handler_instr[$]; + cv32e40p_instr_gen_config corev_cfg; + `DV_CHECK_FATAL($cast(corev_cfg, cfg), "Could not cast cfg into corev_cfg") + ls_unit = (XLEN == 32) ? "w" : "d"; if (mode < cfg.init_privileged_mode) return; if (mode == USER_MODE && !riscv_instr_pkg::support_umode_trap) return; @@ -236,8 +363,13 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen; end // Restore user mode GPR value from kernel stack before return - pop_gpr_from_kernel_stack(status, scratch, cfg.mstatus_mprv, - cfg.sp, cfg.tp, interrupt_handler_instr); + + // Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack + //pop_gpr_from_kernel_stack(status, scratch, cfg.mstatus_mprv, + // cfg.sp, cfg.tp, interrupt_handler_instr); + + pop_regfile_from_kernel_stack(status, scratch, cfg.mstatus_mprv, + cfg.sp, cfg.tp, interrupt_handler_instr, corev_cfg); // Emit fast interrupt handler since cv32e40p has hardware interrupt ack interrupt_handler_instr = {interrupt_handler_instr, @@ -275,8 +407,10 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen; // Override of init_gpr to remove cfg.dp from initiailization if a debug section is generated virtual function void init_gpr(); string str; + string reg_name; bit [DATA_WIDTH-1:0] reg_val; cv32e40p_instr_gen_config cfg_corev; + bit [31:0] imm; `DV_CHECK($cast(cfg_corev, cfg)) // Init general purpose registers with random values @@ -292,7 +426,31 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen; ['h10 : 'hEFFF_FFFF] :/ 1, ['hF000_0000 : 'hFFFF_FFFF] :/ 1 };) - str = $sformatf("%0sli x%0d, 0x%0x", indent, i, reg_val); + str = $sformatf("%0sli%0s x%0d, 0x%0x", indent, indent, i, reg_val); + instr_stream.push_back(str); + end + //after initializing all gprs, for zfinx extention tests again initialize + //gprs for floating point instructions + if(RV32ZFINX inside {supported_isa}) begin + foreach(cfg_corev.zfinx_reserved_gpr[i]) begin + if (cfg_corev.zfinx_reserved_gpr[i] inside {ZERO, RA, SP, GP, TP}) continue; + imm = get_rand_spf_value(); + reg_name = cfg_corev.zfinx_reserved_gpr[i].name(); + str = $sformatf("%0sli%0s %0s, 0x%0x", indent, indent, reg_name.tolower(), imm); + instr_stream.push_back(str); + end + end + + // Initialize reserved registers for store instr + if (!cfg_corev.no_load_store) begin + reg_name = cfg_corev.str_rs1.name(); + reg_val = 32'h80000000; // FIXME : Remove hardcoded value to allow configuration based on linker + str = $sformatf("%0sli%0s %0s, 0x%0x", indent, indent, reg_name.tolower(), reg_val); + instr_stream.push_back(str); + + reg_name = cfg_corev.str_rs3.name(); + reg_val = $urandom_range(0,255); // FIXME : include negative also + str = $sformatf("%0sli%0s %0s, 0x%0x", indent, indent, reg_name.tolower(), reg_val); instr_stream.push_back(str); end endfunction @@ -353,4 +511,129 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen; end endfunction + // Override init_floating_point_gpr + virtual function void init_floating_point_gpr(); + int int_gpr; + string str; + for(int i = 0; i < NUM_FLOAT_GPR; i++) begin + randcase + RV32F inside {supported_isa}: init_floating_point_gpr_with_spf(i); + RV64D inside {supported_isa}: init_floating_point_gpr_with_dpf(i); + endcase + end + // Initialize rounding mode of FCSR + str = $sformatf("%0sfsrmi%0s %0d", indent, indent, cfg.fcsr_rm); + instr_stream.push_back(str); + endfunction + + // Override Ebreak trap handler - gen_ebreak_handler + // Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack + virtual function void gen_ebreak_handler(int hart); + string instr[$]; + cv32e40p_instr_gen_config corev_cfg; + + `DV_CHECK_FATAL($cast(corev_cfg, cfg), "Could not cast cfg into corev_cfg") + + gen_signature_handshake(instr, CORE_STATUS, EBREAK_EXCEPTION); + gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE)); + instr = {instr, + $sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], MEPC), + $sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]), + $sformatf("csrw 0x%0x, x%0d", MEPC, cfg.gpr[0]) + }; + // Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack + //pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr); + pop_regfile_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg); + instr.push_back("mret"); + gen_section(get_label("ebreak_handler", hart), instr); + endfunction + + // Override Illegal instruction handler - gen_illegal_instr_handler + // Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack + virtual function void gen_illegal_instr_handler(int hart); + string instr[$]; + cv32e40p_instr_gen_config corev_cfg; + + `DV_CHECK_FATAL($cast(corev_cfg, cfg), "Could not cast cfg into corev_cfg") + + gen_signature_handshake(instr, CORE_STATUS, ILLEGAL_INSTR_EXCEPTION); + gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE)); + instr = {instr, + $sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], MEPC), + $sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]), + $sformatf("csrw 0x%0x, x%0d", MEPC, cfg.gpr[0]) + }; + // Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack + //pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr); + pop_regfile_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg); + instr.push_back("mret"); + gen_section(get_label("illegal_instr_handler", hart), instr); + endfunction + + // Override gen_instr_fault_handler + // Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack + virtual function void gen_instr_fault_handler(int hart); + string instr[$]; + cv32e40p_instr_gen_config corev_cfg; + + `DV_CHECK_FATAL($cast(corev_cfg, cfg), "Could not cast cfg into corev_cfg") + + gen_signature_handshake(instr, CORE_STATUS, INSTR_FAULT_EXCEPTION); + gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE)); + if (cfg.pmp_cfg.enable_pmp_exception_handler) begin + cfg.pmp_cfg.gen_pmp_exception_routine({cfg.gpr, cfg.scratch_reg, cfg.pmp_reg}, + INSTRUCTION_ACCESS_FAULT, + instr); + end + // Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack + //pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr); + pop_regfile_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg); + instr.push_back("mret"); + gen_section(get_label("instr_fault_handler", hart), instr); + endfunction + + // Override gen_load_fault_handler + // Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack + virtual function void gen_load_fault_handler(int hart); + string instr[$]; + cv32e40p_instr_gen_config corev_cfg; + + `DV_CHECK_FATAL($cast(corev_cfg, cfg), "Could not cast cfg into corev_cfg") + + gen_signature_handshake(instr, CORE_STATUS, LOAD_FAULT_EXCEPTION); + gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE)); + if (cfg.pmp_cfg.enable_pmp_exception_handler) begin + cfg.pmp_cfg.gen_pmp_exception_routine({cfg.gpr, cfg.scratch_reg, cfg.pmp_reg}, + LOAD_ACCESS_FAULT, + instr); + end + // Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack + //pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr); + pop_regfile_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg); + instr.push_back("mret"); + gen_section(get_label("load_fault_handler", hart), instr); + endfunction + + // Override gen_store_fault_handler + // Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack + virtual function void gen_store_fault_handler(int hart); + string instr[$]; + cv32e40p_instr_gen_config corev_cfg; + + `DV_CHECK_FATAL($cast(corev_cfg, cfg), "Could not cast cfg into corev_cfg") + + gen_signature_handshake(instr, CORE_STATUS, STORE_FAULT_EXCEPTION); + gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE)); + if (cfg.pmp_cfg.enable_pmp_exception_handler) begin + cfg.pmp_cfg.gen_pmp_exception_routine({cfg.gpr, cfg.scratch_reg, cfg.pmp_reg}, + STORE_AMO_ACCESS_FAULT, + instr); + end + // Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack + //pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr); + pop_regfile_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg); + instr.push_back("mret"); + gen_section(get_label("store_fault_handler", hart), instr); + endfunction + endclass : cv32e40p_asm_program_gen diff --git a/cv32e40p/env/corev-dv/cv32e40p_debug_rom_gen.sv b/cv32e40p/env/corev-dv/cv32e40p_debug_rom_gen.sv index 2ff4fda420..2104aeabb3 100644 --- a/cv32e40p/env/corev-dv/cv32e40p_debug_rom_gen.sv +++ b/cv32e40p/env/corev-dv/cv32e40p_debug_rom_gen.sv @@ -28,6 +28,7 @@ class cv32e40p_debug_rom_gen extends riscv_debug_rom_gen; virtual function void gen_program(); string sub_program_name[$] = {}; cv32e40p_instr_gen_config cfg_corev; + privileged_reg_t status = MSTATUS; // CORE-V Addition // Insert section info so linker can place @@ -71,7 +72,7 @@ class cv32e40p_debug_rom_gen extends riscv_debug_rom_gen; // Need to save off FPRs incase f-extension instructions are used to avoid modifying program flow if(cfg.enable_floating_point && !cfg.enable_fp_in_x_regs) begin - push_fpr_to_debugger_stack(cfg_corev, debug_main); + push_fpr_to_debugger_stack(cfg_corev, debug_main, status); end // Signal that the core entered debug rom only if the rom is actually // being filled with random instructions to prevent stress tests from @@ -124,7 +125,7 @@ class cv32e40p_debug_rom_gen extends riscv_debug_rom_gen; //pop FPRs for f-extension instructions if(cfg.enable_floating_point && !cfg.enable_fp_in_x_regs) begin - pop_fpr_from_debugger_stack(cfg_corev, debug_end); + pop_fpr_from_debugger_stack(cfg_corev, debug_end, status); end pop_gpr_from_debugger_stack(cfg_corev, debug_end); diff --git a/cv32e40p/env/corev-dv/cv32e40p_instr_base_test.sv b/cv32e40p/env/corev-dv/cv32e40p_instr_base_test.sv index 4192c72ffc..15751cab0f 100644 --- a/cv32e40p/env/corev-dv/cv32e40p_instr_base_test.sv +++ b/cv32e40p/env/corev-dv/cv32e40p_instr_base_test.sv @@ -25,6 +25,8 @@ class cv32e40p_instr_base_test extends corev_instr_base_test; + cv32e40p_instr_gen_config cv32e40p_cfg; + `uvm_component_utils(cv32e40p_instr_base_test) function new(string name="", uvm_component parent=null); @@ -32,10 +34,12 @@ class cv32e40p_instr_base_test extends corev_instr_base_test; endfunction virtual function void build_phase(uvm_phase phase); + cv32e40p_cfg = cv32e40p_instr_gen_config::type_id::create("cv32e40p_cfg"); + uvm_config_db#(cv32e40p_instr_gen_config)::set(null, "*", "cv32e40p_instr_cfg", cv32e40p_cfg); + override_gen_config(); override_instr_type(); override_instr_sequence(); override_asm_program_gen(); - override_gen_config(); override_compressed_instr(); override_illegal_instr(); override_privil_reg(); @@ -44,6 +48,20 @@ class cv32e40p_instr_base_test extends corev_instr_base_test; super.build_phase(phase); endfunction + //Override randomize_cfg to randomize cv32e40p_instr_gen_config object + virtual function void randomize_cfg(); + `DV_CHECK_RANDOMIZE_FATAL(cfg); + + `DV_CHECK_RANDOMIZE_FATAL(cv32e40p_cfg); + `uvm_info(`gfn, $sformatf("cv32e40p_instr_gen_config is randomized:\n%0s", + cv32e40p_cfg.sprint()), UVM_LOW) + + cfg.copy(cv32e40p_cfg); + + `uvm_info(`gfn, $sformatf("riscv_instr_gen_config is randomized:\n%0s", + cfg.sprint()), UVM_LOW) + endfunction + virtual function void override_asm_program_gen(); uvm_factory::get().set_type_override_by_type(corev_asm_program_gen::get_type(), cv32e40p_asm_program_gen::get_type()); @@ -84,20 +102,6 @@ class cv32e40p_instr_base_test extends corev_instr_base_test; end endcase end // TEST_OVERRIDE_RISCV_INSTR_STREAM - if ($value$plusargs("test_override_fp_instr_stream=%s", test_override_fp_instr_stream)) begin : TEST_OVERRIDE_FP_INSTR_STREAM - if (test_override_fp_instr_stream != "default") begin - `uvm_info(this.type_name, $sformatf("uvm_factory override stream to %s", test_override_fp_instr_stream), UVM_NONE); - case (test_override_fp_instr_stream) - "fp_n_mixed_instr": begin uvm_factory::get().set_type_override_by_type(cv32e40p_float_zfinx_base_instr_stream::get_type(), cv32e40p_fp_n_mixed_instr_stream::get_type()); end - "fp_n_mixed_instr_more_fdiv_fsqrt": begin uvm_factory::get().set_type_override_by_type(cv32e40p_float_zfinx_base_instr_stream::get_type(), cv32e40p_fp_n_mixed_instr_more_fdiv_fsqrt_stream::get_type()); end - "fp_w_special_operands": begin uvm_factory::get().set_type_override_by_type(cv32e40p_float_zfinx_base_instr_stream::get_type(), cv32e40p_fp_w_special_operands_instr_stream::get_type()); end - "fp_w_prev_rd_as_operand": begin uvm_factory::get().set_type_override_by_type(cv32e40p_float_zfinx_base_instr_stream::get_type(), cv32e40p_fp_w_prev_rd_as_operand_instr_stream::get_type()); end - "constraint_mc_fp": begin uvm_factory::get().set_type_override_by_type(cv32e40p_float_zfinx_base_instr_stream::get_type(), cv32e40p_constraint_mc_fp_instr_stream::get_type()); end - "fp_operand_forwarding": begin uvm_factory::get().set_type_override_by_type(cv32e40p_float_zfinx_base_instr_stream::get_type(), cv32e40p_fp_operand_forwarding_instr_stream::get_type()); end - "fp_followed_by_csrr": begin uvm_factory::get().set_type_override_by_type(cv32e40p_float_zfinx_base_instr_stream::get_type(), cv32e40p_fp_followed_by_csrr_instr_stream::get_type()); end - endcase - end - end // TEST_OVERRIDE_FP_INSTR_STREAM endfunction virtual function void override_instr_sequence(); diff --git a/cv32e40p/env/corev-dv/cv32e40p_instr_gen_config.sv b/cv32e40p/env/corev-dv/cv32e40p_instr_gen_config.sv index 370641fac2..c034f45ab5 100644 --- a/cv32e40p/env/corev-dv/cv32e40p_instr_gen_config.sv +++ b/cv32e40p/env/corev-dv/cv32e40p_instr_gen_config.sv @@ -45,6 +45,35 @@ class cv32e40p_instr_gen_config extends riscv_instr_gen_config; // Config to specify number of rand_directed_instr_* passed in test plusargs int test_rand_directed_instr_stream_num = 1; + rand int num_zfinx_reserved_reg; + + rand riscv_reg_t zfinx_reserved_gpr[]; + + rand bit ss_dbg_high_iteration_cnt; + + bit is_hwloop_test = 0; + + rand bit xpulp_instr_in_debug_rom; + + // Random rs1, rs3 for store instr + rand riscv_reg_t str_rs1; + rand riscv_reg_t str_rs3; + + constraint ss_dbg_high_iteration_cnt_c { + ss_dbg_high_iteration_cnt dist {0 := 60, 1 := 40}; + } + + // Override single step constraint + constraint debug_single_step_c { + solve ss_dbg_high_iteration_cnt before single_step_iterations; + if (enable_debug_single_step & is_hwloop_test & ss_dbg_high_iteration_cnt) { + single_step_iterations inside {[1000 : 5000]}; + } + else if (enable_debug_single_step) { + single_step_iterations inside {[10 : 50]}; + } + } + constraint dp_c { // Debug pointer may not be the return address, stack pointer, nor thread pointer if (!gen_debug_section) { @@ -87,13 +116,65 @@ class cv32e40p_instr_gen_config extends riscv_instr_gen_config; } } + constraint num_zfinx_reserved_reg_c { + if (RV32ZFINX inside {riscv_instr_pkg::supported_isa}) { + num_zfinx_reserved_reg inside {[5:10]}; + } else { + num_zfinx_reserved_reg == 0; + } + } + + constraint zfinx_reserved_gpr_c { + solve num_zfinx_reserved_reg, dp, str_rs1, str_rs3 before zfinx_reserved_gpr; + if (RV32ZFINX inside {riscv_instr_pkg::supported_isa}) { + zfinx_reserved_gpr.size() == num_zfinx_reserved_reg; + unique {zfinx_reserved_gpr}; + foreach(zfinx_reserved_gpr[i]) { + !(zfinx_reserved_gpr[i] inside {ZERO, RA, SP, GP, TP}); + (zfinx_reserved_gpr[i] != dp); + (zfinx_reserved_gpr[i] != str_rs1); + (zfinx_reserved_gpr[i] != str_rs3); + } + + } else { + zfinx_reserved_gpr.size() == 0; + } + } + + constraint xpulp_instr_in_debug_rom_c { + xpulp_instr_in_debug_rom dist {0 := 1, 1 := 2}; + } + + constraint str_rs1_rs3_c { + solve dp before str_rs1, str_rs3; + if(!no_load_store) { + !(str_rs1 inside {sp, tp, ra, scratch_reg, GP, RA, ZERO, dp}); + str_rs1 inside {[S0:A5]}; // TODO: remove range constrained due to compressed stores + !(str_rs3 inside {sp, tp, ra, scratch_reg, GP, RA, ZERO, dp}); + str_rs3 inside {[S0:A5]}; // TODO: remove range constrained due to compressed stores + str_rs1 != str_rs3; //TODO : check if this can be removed + } else { + str_rs1 == ZERO; + str_rs3 == ZERO; + } + } + `uvm_object_utils_begin(cv32e40p_instr_gen_config) `uvm_field_enum(mtvec_mode_t, mtvec_mode, UVM_DEFAULT) `uvm_field_int(knob_zero_fast_intr_handlers, UVM_DEFAULT) `uvm_field_enum(riscv_reg_t, dp, UVM_DEFAULT) `uvm_field_enum(riscv_reg_t, scratch_reg, UVM_DEFAULT) `uvm_field_int(enable_fast_interrupt_handler, UVM_DEFAULT) - `uvm_field_int(use_fast_intr_handler, UVM_DEFAULT) + `uvm_field_int(use_fast_intr_handler, UVM_DEFAULT) + `uvm_field_int(insert_rand_directed_instr_stream, UVM_DEFAULT) + `uvm_field_int(test_rand_directed_instr_stream_num, UVM_DEFAULT) + `uvm_field_int(num_zfinx_reserved_reg, UVM_DEFAULT) + `uvm_field_array_enum(riscv_reg_t, zfinx_reserved_gpr, UVM_DEFAULT) + `uvm_field_int(ss_dbg_high_iteration_cnt, UVM_DEFAULT) + `uvm_field_int(is_hwloop_test, UVM_DEFAULT) + `uvm_field_int(xpulp_instr_in_debug_rom, UVM_DEFAULT) + `uvm_field_enum(riscv_reg_t, str_rs1, UVM_DEFAULT) + `uvm_field_enum(riscv_reg_t, str_rs3, UVM_DEFAULT) `uvm_object_utils_end function new(string name=""); @@ -102,6 +183,7 @@ class cv32e40p_instr_gen_config extends riscv_instr_gen_config; get_bool_arg_value("+enable_fast_interrupt_handler=", enable_fast_interrupt_handler); get_bool_arg_value("+insert_rand_directed_instr_stream=", insert_rand_directed_instr_stream); get_int_arg_value("+test_rand_directed_instr_stream_num=", test_rand_directed_instr_stream_num); + get_bool_arg_value("+is_hwloop_test=", is_hwloop_test); endfunction : new function void post_randomize(); @@ -110,8 +192,16 @@ class cv32e40p_instr_gen_config extends riscv_instr_gen_config; // Add in the debug pointer to reserved registers if we are using it if (gen_debug_section) begin reserved_regs = {tp, sp, scratch_reg, dp}; + end else begin + reserved_regs = {tp, sp, scratch_reg}; end + if (zfinx_reserved_gpr.size()!= 0) + reserved_regs = {reserved_regs, zfinx_reserved_gpr}; + + if (!no_load_store) + reserved_regs = {reserved_regs, str_rs1, str_rs3}; + // In the debug ROM some combinations are not valid because they use the same register (dscratch0) if (gen_debug_section) begin if ((enable_ebreak_in_debug_rom || set_dcsr_ebreak) && @@ -120,7 +210,8 @@ class cv32e40p_instr_gen_config extends riscv_instr_gen_config; $sformatf("Illegal combination of debug plusargs: enable_ebreak_in_debug_rom = %0d, set_dcsr_ebreakl = %0d, enable_debug_single_step = %0d", enable_ebreak_in_debug_rom, set_dcsr_ebreak, enable_debug_single_step)) end - end + end + endfunction : post_randomize endclass : cv32e40p_instr_gen_config diff --git a/cv32e40p/env/corev-dv/cv32e40p_instr_sequence.sv b/cv32e40p/env/corev-dv/cv32e40p_instr_sequence.sv index 944c1a8e43..a1181be52c 100644 --- a/cv32e40p/env/corev-dv/cv32e40p_instr_sequence.sv +++ b/cv32e40p/env/corev-dv/cv32e40p_instr_sequence.sv @@ -28,10 +28,15 @@ class cv32e40p_instr_sequence extends riscv_instr_sequence; + cv32e40p_instr_gen_config cv32e40p_cfg; + `uvm_object_utils(cv32e40p_instr_sequence) function new (string name = ""); super.new(name); + if(!uvm_config_db#(cv32e40p_instr_gen_config)::get(null, "*", "cv32e40p_instr_cfg", cv32e40p_cfg)) begin + `uvm_fatal(get_full_name(), "Cannot get cv32e40p_instr_gen_config") + end endfunction //Function: cv32e40p_instr_sequence::post_process_instr() diff --git a/cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv b/cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv index 3ea92daed3..63aa757eef 100644 --- a/cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv +++ b/cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv @@ -24,6 +24,7 @@ package cv32e40p_instr_test_pkg; import riscv_signature_pkg::*; import corev_instr_test_pkg::*; + `include "cv32e40p_instr_gen_config.sv" // Instruction streams specific to CV32E40P // `include "instr_lib/cv32e40p_load_store_instr_lib.sv" `include "instr_lib/cv32e40p_base_instr_lib.sv" @@ -37,7 +38,6 @@ package cv32e40p_instr_test_pkg; `include "cv32e40p_compressed_instr.sv" `include "cv32e40p_illegal_instr.sv" `include "cv32e40p_privil_reg.sv" - `include "cv32e40p_instr_gen_config.sv" `include "cv32e40p_debug_rom_gen.sv" `include "cv32e40p_asm_program_gen.sv" `include "cv32e40p_instr_base_test.sv" @@ -53,20 +53,84 @@ package cv32e40p_instr_test_pkg; if (i == cfg_corev.dp) continue; if (i == cfg_corev.sp) continue; if (i == cfg_corev.tp) continue; - instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, i, i * (XLEN/8), cfg_corev.dp)); + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, i, (i-1) * (XLEN/8), cfg_corev.dp)); end endfunction : push_gpr_to_debugger_stack // Push floating point registers to the debugger stack function automatic void push_fpr_to_debugger_stack(cv32e40p_instr_gen_config cfg_corev, - ref string instr[$]); - string store_instr = (FLEN == 32) ? "fsw" : "fsd"; - // Reserve space from kernel stack to save all 32 FPR except for x0 - instr.push_back($sformatf("1: addi x%0d, x%0d, -%0d", cfg_corev.dp, cfg_corev.dp, 31 * (XLEN/8))); + ref string instr[$], + privileged_reg_t status); + string store_instr; + + randcase + 1: store_instr = (FLEN == 32) ? "fsw" : "fsd"; + (cfg_corev.dp == 2): store_instr = (FLEN == 32) ? "c.fswsp" : "fsd"; + endcase + + //Check if mstatus.FS != 3 ,i.e., Not "Dirty" state + instr.push_back($sformatf("csrr x%0d, 0x%0x # %0s", cfg_corev.gpr[0], status, status.name())); + instr.push_back($sformatf("srli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("andi x%0d, x%0d, 0x3", cfg_corev.gpr[0], cfg_corev.gpr[0])); //Check MSTATUS.FS bit + instr.push_back($sformatf("li x%0d, 0x%0x", cfg_corev.gpr[1], 3)); + instr.push_back($sformatf("bne x%0d, x%0d, 2f", cfg_corev.gpr[0], cfg_corev.gpr[1])); // MSTATUS.FS!=3 do not push + + // Reserve space from kernel stack to save all 32 FPR + FCSR + MSTATUS + instr.push_back($sformatf("1: addi x%0d, x%0d, -%0d", cfg_corev.dp, cfg_corev.dp, 33 * (XLEN/8))); // Push all FPRs to kernel stack - for(int i = 1; i < 32; i++) begin + for(int i = 0; i < 32; i++) begin instr.push_back($sformatf("%0s f%0d, %0d(x%0d)", store_instr, i, i * (FLEN/8), cfg_corev.dp)); end + + store_instr = (XLEN == 32) ? "sw" : "sd"; + + // Push FCSR to kernel stack + instr.push_back($sformatf("fscsr x%0d, x0", cfg_corev.gpr[0])); // Read and Clear FCSR + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg_corev.gpr[0], 32 * (XLEN/8), cfg_corev.dp)); + + // Reserve space from kernel stack to save MSTATUS.FS + instr.push_back($sformatf("addi x%0d, x%0d, -%0d", cfg_corev.dp, cfg_corev.dp, 1 * (XLEN/8))); + + // Push MSTATUS.FS to kernel stack + instr.push_back($sformatf("csrr x%0d, 0x%0x # %0s", cfg_corev.gpr[0], status, status.name())); + instr.push_back($sformatf("srli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("andi x%0d, x%0d, 0x3", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg_corev.gpr[0], 0, cfg_corev.dp)); + + //Set the MSTATUS.FS status to Clean + instr.push_back($sformatf("li x%0d, 0x%0x", cfg_corev.gpr[0], 1)); //Set FS from 3->2 Clean, clear bit 13 + instr.push_back($sformatf("slli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("csrrc x0, 0x%0x, x%0d # %0s", status, cfg_corev.gpr[0], status.name())); + + instr.push_back($sformatf("j 3f")); + + instr.push_back($sformatf("2: nop")); //BNE 2f Target + + // Reserve space from kernel stack to save MSTATUS.FS + instr.push_back($sformatf("addi x%0d, x%0d, -%0d", cfg_corev.dp, cfg_corev.dp, 1 * (XLEN/8))); + + // Push MSTATUS.FS to kernel stack + instr.push_back($sformatf("csrr x%0d, 0x%0x # %0s", cfg_corev.gpr[0], status, status.name())); + instr.push_back($sformatf("srli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("andi x%0d, x%0d, 0x3", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg_corev.gpr[0], 0, cfg_corev.dp)); + + instr.push_back($sformatf("3: nop")); //Jump 3f Target + + //Check if mstatus.FS != 0 ,i.e., Not "All Off" state + instr.push_back($sformatf("csrr x%0d, 0x%0x # %0s", cfg_corev.gpr[0], status, status.name())); + instr.push_back($sformatf("srli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("andi x%0d, x%0d, 0x3", cfg_corev.gpr[0], cfg_corev.gpr[0])); //Check MSTATUS.FS bit + instr.push_back($sformatf("bnez x%0d, 4f", cfg_corev.gpr[0])); // check MSTATUS.FS!=0 + + // if MSTATUS.FS==0 set MSTATUS.FS to Initial + instr.push_back($sformatf("li x%0d, 0x%0x", cfg_corev.gpr[0], 1)); //Change FS from 0 to 1, i.e., Initial + instr.push_back($sformatf("slli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("csrrs x0, 0x%0x, x%0d # %0s", status, cfg_corev.gpr[0], status.name())); + + instr.push_back($sformatf("4: nop")); //BNE 4f Target + + endfunction : push_fpr_to_debugger_stack // Pop general purpose register from debugger stack @@ -78,7 +142,7 @@ package cv32e40p_instr_test_pkg; if (i == cfg_corev.dp) continue; if (i == cfg_corev.sp) continue; if (i == cfg_corev.tp) continue; - instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, i, i * (XLEN/8), cfg_corev.dp)); + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, i, (i-1) * (XLEN/8), cfg_corev.dp)); end // Restore debugger stack pointer instr.push_back($sformatf("addi x%0d, x%0d, %0d", cfg_corev.dp, cfg_corev.dp, 31 * (XLEN/8))); @@ -86,14 +150,48 @@ package cv32e40p_instr_test_pkg; // Pop floating point register from debugger stack function automatic void pop_fpr_from_debugger_stack(cv32e40p_instr_gen_config cfg_corev, - ref string instr[$]); - string load_instr = (FLEN == 32) ? "flw" : "fld"; - // Pop user mode FPRs from kernel stack - for(int i = 1; i < 32; i++) begin + ref string instr[$], + privileged_reg_t status); + string load_instr; + + load_instr = (XLEN == 32) ? "lw" : "ld"; + + // Pop MSTATUS.FS from kernel stack + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg_corev.gpr[0], 0, cfg_corev.dp)); + // Restore MSTATUS.FS + instr.push_back($sformatf("li x%0d, 0x%0x", cfg_corev.gpr[1], 3)); //Clear FS + instr.push_back($sformatf("slli x%0d, x%0d, 13", cfg_corev.gpr[1], cfg_corev.gpr[1])); + instr.push_back($sformatf("csrrc x0, 0x%0x, x%0d # %0s", status, cfg_corev.gpr[1], status.name())); + instr.push_back($sformatf("slli x%0d, x%0d, 13", cfg_corev.gpr[1], cfg_corev.gpr[0])); + instr.push_back($sformatf("csrrs x0, 0x%0x, x%0d # %0s", status, cfg_corev.gpr[1], status.name())); + + // Restore kernel stack pointer + instr.push_back($sformatf("addi x%0d, x%0d, %0d", cfg_corev.dp, cfg_corev.dp, 1 * (XLEN/8))); + + instr.push_back($sformatf("li x%0d, 0x%0x", cfg_corev.gpr[1], 3)); + instr.push_back($sformatf("bne x%0d, x%0d, 2f", cfg_corev.gpr[0], cfg_corev.gpr[1])); // MSTATUS.FS!=3 do not pop FPR + + randcase + 1: load_instr = (FLEN == 32) ? "flw" : "fld"; + (cfg_corev.dp == 2): load_instr = (FLEN == 32) ? "c.flwsp" : "fld"; + endcase + + // Pop FPRs from kernel stack + for(int i = 0; i < 32; i++) begin instr.push_back($sformatf("%0s f%0d, %0d(x%0d)", load_instr, i, i * (FLEN/8), cfg_corev.dp)); end + + load_instr = (XLEN == 32) ? "lw" : "ld"; + + // Pop FCSR from kernel stack + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg_corev.gpr[1], 32 * (XLEN/8), cfg_corev.dp)); + instr.push_back($sformatf("fscsr x%0d", cfg_corev.gpr[1])); // Restore FCSR + // Restore debugger stack pointer - instr.push_back($sformatf("addi x%0d, x%0d, %0d", cfg_corev.dp, cfg_corev.dp, 31 * (XLEN/8))); + instr.push_back($sformatf("addi x%0d, x%0d, %0d", cfg_corev.dp, cfg_corev.dp, 33 * (XLEN/8))); + + instr.push_back($sformatf("2: nop")); //BNE 2f Target + endfunction : pop_fpr_from_debugger_stack //Function: check_str_pattern_match @@ -124,4 +222,187 @@ package cv32e40p_instr_test_pkg; endfunction + // Push general purpose register to stack, this is needed before trap handling + // Push fpr to stack if rv32f exists + function automatic void push_regfile_to_kernel_stack(privileged_reg_t status, + privileged_reg_t scratch, + bit mprv, + riscv_reg_t sp, + riscv_reg_t tp, + ref string instr[$], + cv32e40p_instr_gen_config cfg_corev); + string store_instr = (XLEN == 32) ? "sw" : "sd"; + if (scratch inside {implemented_csr}) begin + // Use kernal stack for handling exceptions + // Save the user mode stack pointer to the scratch register + instr.push_back($sformatf("csrrw x%0d, 0x%0x, x%0d", sp, scratch, sp)); + // Move TP to SP + instr.push_back($sformatf("add x%0d, x%0d, zero", sp, tp)); + end + // If MPRV is set and MPP is S/U mode, it means the address translation and memory protection + // for load/store instruction is the same as the mode indicated by MPP. In this case, we + // need to use the virtual address to access the kernel stack. + if((status == MSTATUS) && (SATP_MODE != BARE)) begin + // We temporarily use tp to check mstatus to avoid changing other GPR. The value of sp has + // been saved to xScratch and can be restored later. + if(mprv) begin + instr.push_back($sformatf("csrr x%0d, 0x%0x // MSTATUS", tp, status)); + instr.push_back($sformatf("srli x%0d, x%0d, 11", tp, tp)); // Move MPP to bit 0 + instr.push_back($sformatf("andi x%0d, x%0d, 0x3", tp, tp)); // keep the MPP bits + // Check if MPP equals to M-mode('b11) + instr.push_back($sformatf("xori x%0d, x%0d, 0x3", tp, tp)); + instr.push_back($sformatf("bnez x%0d, 1f", tp)); // Use physical address for kernel SP + // Use virtual address for stack pointer + instr.push_back($sformatf("slli x%0d, x%0d, %0d", sp, sp, XLEN - MAX_USED_VADDR_BITS)); + instr.push_back($sformatf("srli x%0d, x%0d, %0d", sp, sp, XLEN - MAX_USED_VADDR_BITS)); + end + end + // Reserve space from kernel stack to save all 32 GPR except for x0 + instr.push_back($sformatf("1: addi x%0d, x%0d, -%0d", sp, sp, 31 * (XLEN/8))); + // Push all GPRs to kernel stack + for(int i = 1; i < 32; i++) begin + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, i, (i-1) * (XLEN/8), sp)); + end + + if(cfg_corev.enable_floating_point && !cfg_corev.enable_fp_in_x_regs) begin + randcase + 1: store_instr = (FLEN == 32) ? "fsw" : "fsd"; + (sp == 2): store_instr = (FLEN == 32) ? "c.fswsp" : "fsd"; + endcase + + //Check if mstatus.FS != 3 ,i.e., Not "Dirty" state + instr.push_back($sformatf("csrr x%0d, 0x%0x # %0s", cfg_corev.gpr[0], status, status.name())); + instr.push_back($sformatf("srli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("andi x%0d, x%0d, 0x3", cfg_corev.gpr[0], cfg_corev.gpr[0])); //Check MSTATUS.FS bit + instr.push_back($sformatf("li x%0d, 0x%0x", cfg_corev.gpr[1], 3)); + instr.push_back($sformatf("bne x%0d, x%0d, 2f", cfg_corev.gpr[0], cfg_corev.gpr[1])); // MSTATUS.FS!=3 do not push + + // Reserve space from kernel stack to save all 32 FPR + FCSR + instr.push_back($sformatf("addi x%0d, x%0d, -%0d", sp, sp, 33 * (XLEN/8))); + // Push all FPRs to kernel stack + for(int i = 0; i < 32; i++) begin + instr.push_back($sformatf("%0s f%0d, %0d(x%0d)", store_instr, i, i * (XLEN/8), sp)); + end + + store_instr = (XLEN == 32) ? "sw" : "sd"; + + // Push FCSR to kernel stack + instr.push_back($sformatf("fscsr x%0d, x0", cfg_corev.gpr[0])); // Read and Clear FCSR + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg_corev.gpr[0], 32 * (XLEN/8), sp)); + + // Reserve space from kernel stack to save MSTATUS.FS + instr.push_back($sformatf("addi x%0d, x%0d, -%0d", sp, sp, 1 * (XLEN/8))); + + // Push MSTATUS.FS to kernel stack + instr.push_back($sformatf("csrr x%0d, 0x%0x # %0s", cfg_corev.gpr[0], status, status.name())); + instr.push_back($sformatf("srli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("andi x%0d, x%0d, 0x3", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg_corev.gpr[0], 0, sp)); + + //Set the MSTATUS.FS status to Clean + instr.push_back($sformatf("li x%0d, 0x%0x", cfg_corev.gpr[0], 1)); //Set FS from 3->2 Clean, clear bit 13 + instr.push_back($sformatf("slli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("csrrc x0, 0x%0x, x%0d # %0s", status, cfg_corev.gpr[0], status.name())); + + instr.push_back($sformatf("j 3f")); + + instr.push_back($sformatf("2: nop")); //BNE 2f Target + + // Reserve space from kernel stack to save MSTATUS.FS + instr.push_back($sformatf("addi x%0d, x%0d, -%0d", sp, sp, 1 * (XLEN/8))); + + // Push MSTATUS.FS to kernel stack + instr.push_back($sformatf("csrr x%0d, 0x%0x # %0s", cfg_corev.gpr[0], status, status.name())); + instr.push_back($sformatf("srli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("andi x%0d, x%0d, 0x3", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg_corev.gpr[0], 0, sp)); + + instr.push_back($sformatf("3: nop")); //Jump 3f Target + + //Check if mstatus.FS != 0 ,i.e., Not "All Off" state + instr.push_back($sformatf("csrr x%0d, 0x%0x # %0s", cfg_corev.gpr[0], status, status.name())); + instr.push_back($sformatf("srli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("andi x%0d, x%0d, 0x3", cfg_corev.gpr[0], cfg_corev.gpr[0])); //Check MSTATUS.FS bit + instr.push_back($sformatf("bnez x%0d, 4f", cfg_corev.gpr[0])); // check MSTATUS.FS!=0 + + // if MSTATUS.FS==0 set MSTATUS.FS to Initial + instr.push_back($sformatf("li x%0d, 0x%0x", cfg_corev.gpr[0], 1)); //Change FS from 0 to 1, i.e., Initial + instr.push_back($sformatf("slli x%0d, x%0d, 13", cfg_corev.gpr[0], cfg_corev.gpr[0])); + instr.push_back($sformatf("csrrs x0, 0x%0x, x%0d # %0s", status, cfg_corev.gpr[0], status.name())); + + instr.push_back($sformatf("4: nop")); //BNE 4f Target + + end + + endfunction + + // Pop general purpose register from stack + FPR + FCSR + function automatic void pop_regfile_from_kernel_stack(privileged_reg_t status, + privileged_reg_t scratch, + bit mprv, + riscv_reg_t sp, + riscv_reg_t tp, + ref string instr[$], + cv32e40p_instr_gen_config cfg_corev); + + + string load_instr; + + if(cfg_corev.enable_floating_point && !cfg_corev.enable_fp_in_x_regs) begin + load_instr = (XLEN == 32) ? "lw" : "ld"; + + // Pop MSTATUS.FS from kernel stack + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg_corev.gpr[0], 0, sp)); + // Restore MSTATUS.FS + instr.push_back($sformatf("li x%0d, 0x%0x", cfg_corev.gpr[1], 3)); //Clear FS + instr.push_back($sformatf("slli x%0d, x%0d, 13", cfg_corev.gpr[1], cfg_corev.gpr[1])); + instr.push_back($sformatf("csrrc x0, 0x%0x, x%0d # %0s", status, cfg_corev.gpr[1], status.name())); + instr.push_back($sformatf("slli x%0d, x%0d, 13", cfg_corev.gpr[1], cfg_corev.gpr[0])); + instr.push_back($sformatf("csrrs x0, 0x%0x, x%0d # %0s", status, cfg_corev.gpr[1], status.name())); + + // Restore kernel stack pointer + instr.push_back($sformatf("addi x%0d, x%0d, %0d", sp, sp, 1 * (XLEN/8))); + + instr.push_back($sformatf("li x%0d, 0x%0x", cfg_corev.gpr[1], 3)); + instr.push_back($sformatf("bne x%0d, x%0d, 2f", cfg_corev.gpr[0], cfg_corev.gpr[1])); // MSTATUS.FS!=3 do not pop FPR + + randcase + 1: load_instr = (FLEN == 32) ? "flw" : "fld"; + (sp == 2): load_instr = (FLEN == 32) ? "c.flwsp" : "fld"; + endcase + + // Pop FPRs from kernel stack + for(int i = 0; i < 32; i++) begin + instr.push_back($sformatf("%0s f%0d, %0d(x%0d)", load_instr, i, i * (FLEN/8), sp)); + end + + load_instr = (XLEN == 32) ? "lw" : "ld"; + + // Pop FCSR from kernel stack + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg_corev.gpr[1], 32 * (XLEN/8), sp)); + instr.push_back($sformatf("fscsr x%0d", cfg_corev.gpr[1])); // Restore FCSR + + // Restore kernel stack pointer + instr.push_back($sformatf("addi x%0d, x%0d, %0d", sp, sp, 33 * (XLEN/8))); + + instr.push_back($sformatf("2: nop")); //BNE 2f Target + + end + + load_instr = (XLEN == 32) ? "lw" : "ld"; + // Pop user mode GPRs from kernel stack + for(int i = 1; i < 32; i++) begin + instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, i, (i-1) * (XLEN/8), sp)); + end + // Restore kernel stack pointer + instr.push_back($sformatf("addi x%0d, x%0d, %0d", sp, sp, 31 * (XLEN/8))); + if (scratch inside {implemented_csr}) begin + // Move SP to TP + instr.push_back($sformatf("add x%0d, x%0d, zero", tp, sp)); + // Restore user mode stack pointer + instr.push_back($sformatf("csrrw x%0d, 0x%0x, x%0d", sp, scratch, sp)); + end + endfunction + + endpackage : cv32e40p_instr_test_pkg; diff --git a/cv32e40p/env/corev-dv/cv32e40p_rand_instr_stream.sv b/cv32e40p/env/corev-dv/cv32e40p_rand_instr_stream.sv index 6e53a14fe5..8127ea318c 100644 --- a/cv32e40p/env/corev-dv/cv32e40p_rand_instr_stream.sv +++ b/cv32e40p/env/corev-dv/cv32e40p_rand_instr_stream.sv @@ -26,9 +26,16 @@ class cv32e40p_rand_instr_stream extends riscv_rand_instr_stream; protected int idx_start[$]; protected int idx_end[$]; protected int idx_min = 0; + cv32e40p_instr_gen_config cv32e40p_cfg; `uvm_object_utils(cv32e40p_rand_instr_stream) - `uvm_object_new + //`uvm_object_new + function new(string name = ""); + super.new(name); + if(!uvm_config_db#(cv32e40p_instr_gen_config)::get(null,get_full_name(),"cv32e40p_instr_cfg", cv32e40p_cfg)) begin + `uvm_fatal(get_full_name(), "Cannot get cv32e40p_instr_gen_config") + end + endfunction : new virtual function void insert_instr_stream(riscv_instr new_instr[], int idx = -1, bit replace = 1'b0); @@ -148,12 +155,16 @@ class cv32e40p_rand_instr_stream extends riscv_rand_instr_stream; bit is_debug_program = 1'b0); setup_allowed_instr(no_branch, no_load_store); - //Use this plusarg - add_xpulp_instr_in_debug_rom to include xpulp instr - //in random debug_rom instructions. Added for v2 debug tests with xpulp. - if ($test$plusargs("add_xpulp_instr_in_debug_rom") && is_debug_program) begin - foreach(instr_list[i]) - randomize_debug_rom_instr(.instr(instr_list[i]), .is_in_debug(is_debug_program), .disable_dist(), .include_group({RV32X})); - `uvm_info("cv32e40p_rand_instr_stream", $sformatf("add_xpulp_instr_in_debug_rom set- Including xpulp instr in debug_rom"), UVM_DEBUG); + //Use this plusarg - include_xpulp_instr_in_debug_rom to include xpulp instr + //In random debug_rom instructions. Added for v2 debug tests with xpulp. + if (cv32e40p_cfg.xpulp_instr_in_debug_rom && is_debug_program && $test$plusargs("include_xpulp_instr_in_debug_rom")) begin + foreach(instr_list[i]) begin + randcase + 1: randomize_debug_rom_instr(.instr(instr_list[i]), .is_in_debug(is_debug_program), .disable_dist()); + 2: randomize_instr(instr_list[i], is_debug_program); + endcase + `uvm_info("cv32e40p_rand_instr_stream", $sformatf("include_xpulp_instr_in_debug_rom set- Including xpulp instr in debug_rom"), UVM_LOW) + end end else begin foreach(instr_list[i]) @@ -183,9 +194,9 @@ class cv32e40p_rand_instr_stream extends riscv_rand_instr_stream; // Post-process the allowed_instr and exclude_instr lists to handle // adding ebreak instructions to the debug rom. if (is_in_debug) begin - if (cfg.no_ebreak && cfg.enable_ebreak_in_debug_rom) begin + if (cfg.enable_ebreak_in_debug_rom) begin allowed_instr = {allowed_instr, EBREAK, C_EBREAK}; - end else if (!cfg.no_ebreak && !cfg.enable_ebreak_in_debug_rom) begin + end else begin exclude_instr = {exclude_instr, EBREAK, C_EBREAK}; end end diff --git a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_base_instr_lib.sv b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_base_instr_lib.sv index c042a45173..22a0801e53 100644 --- a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_base_instr_lib.sv +++ b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_base_instr_lib.sv @@ -21,6 +21,7 @@ class cv32e40p_base_instr_stream extends riscv_rand_instr_stream; rand bit [31:0] temp_imm; // variable used for immediate value randomization + cv32e40p_instr_gen_config cv32e40p_cfg; `uvm_object_utils(cv32e40p_base_instr_stream) int unsigned num_of_avail_regs; @@ -30,6 +31,7 @@ endfunction function void pre_randomize(); + `DV_CHECK_FATAL($cast(cv32e40p_cfg, cfg), "Could not cast cfg into cv32e40p_cfg") super.pre_randomize(); endfunction @@ -78,7 +80,7 @@ function void randomize_cv32e40p_gpr(cv32e40p_instr instr, riscv_reg_t avail_reg_list[]); instr.set_rand_mode(); `DV_CHECK_RANDOMIZE_WITH_FATAL(instr, - if ( (instr.format != (CI_FORMAT || CB_FORMAT || CJ_FORMAT || CR_FORMAT || CA_FORMAT || CL_FORMAT || CS_FORMAT || CSS_FORMAT || CIW_FORMAT)) ) { + if ( (format != (CI_FORMAT || CB_FORMAT || CJ_FORMAT || CR_FORMAT || CA_FORMAT || CL_FORMAT || CS_FORMAT || CSS_FORMAT || CIW_FORMAT)) ) { if (avail_reg_list.size() > 0) { if (has_rs1) { rs1 inside {avail_reg_list}; @@ -97,6 +99,9 @@ if (format == CB_FORMAT) { rs1 != reserved_rd[i]; } + if ((category == POST_INC_LOAD) || (category == POST_INC_STORE)) { + rs1 != reserved_rd[i]; + } } foreach (cfg.reserved_regs[i]) { if (has_rd) { @@ -105,10 +110,19 @@ if (format == CB_FORMAT) { rs1 != cfg.reserved_regs[i]; } + if ((category == POST_INC_LOAD) || (category == POST_INC_STORE)) { + rs1 != cfg.reserved_regs[i]; + } } } // TODO: Add constraint for CSR, floating point register ) + + if (instr.instr_name inside {SB, SH, SW, C_SW, C_FSW, FSW, CV_SB, CV_SH, CV_SW}) begin + instr.rs1 = cv32e40p_cfg.str_rs1; + instr.rd = cv32e40p_cfg.str_rs3; + end + endfunction //Function: randomize_cv32e40p_instr_imm() @@ -201,4 +215,44 @@ end endfunction + //Function: randomize_zfinx_gpr() + function void randomize_zfinx_gpr(riscv_fp_in_x_regs_instr instr, riscv_reg_t avail_reg_list[]); + instr.set_rand_mode(); + `DV_CHECK_RANDOMIZE_WITH_FATAL(instr, + if ( (format != (CI_FORMAT || CB_FORMAT || CJ_FORMAT || CR_FORMAT || CA_FORMAT || CL_FORMAT || CS_FORMAT || CSS_FORMAT || CIW_FORMAT)) ) { + if (avail_reg_list.size() > 0) { + if (has_rs1) { + rs1 inside {avail_reg_list}; + } + if (has_rs2) { + rs2 inside {avail_reg_list}; + } + if (has_rs3) { + rs3 inside {avail_reg_list}; + } + if (has_rd) { + rd inside {avail_reg_list}; + } + } + foreach (reserved_rd[i]) { + if (has_rd) { + rd != reserved_rd[i]; + } + if (format == CB_FORMAT) { + rs1 != reserved_rd[i]; + } + } + } + ) + endfunction + + // Function to assign reserved reg for store instr from cfg to avoid random + // reg operands for stores which may result in corruption of instr memory + function void store_instr_gpr_handling(riscv_instr instr); + if (instr.instr_name inside {SB, SH, SW, C_SW, C_FSW, FSW, CV_SB, CV_SH, CV_SW}) begin + instr.rs1 = cv32e40p_cfg.str_rs1; + instr.rd = cv32e40p_cfg.str_rs3; + end + endfunction + endclass // cv32e40p_base_instr_stream diff --git a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib.sv b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib.sv index f6f839e011..4ec4bfb025 100644 --- a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib.sv +++ b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib.sv @@ -35,23 +35,24 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; // typedef - start typedef enum bit [4:0] { IS_RAND = 0, - IS_POSITIVE_ZERO, /* 'd0 */ - IS_NEGATIVE_ZERO, /* 'd524288 */ - IS_POSITIVE_INFINITY, /* 'd522240 */ - IS_NEGATIVE_INFINITY, /* 'd1046528 */ + IS_POSITIVE_ZERO, + IS_NEGATIVE_ZERO, + IS_POSITIVE_INFINITY, + IS_NEGATIVE_INFINITY, IS_POSITIVE_MAX, IS_NEGATIVE_MAX, IS_POSITIVE_MIN, IS_NEGATIVE_MIN, - IS_POSITIVE_SUBNORMAL, - IS_NEGATIVE_SUBNORMAL, - IS_Q_NAN, /* => 'd1047552 < mantissa all_ones */ - IS_S_NAN, /* => 'd1046528 and < 'dd1047552 */ - W_IS_AT_PERCISION_MAX, - W_IS_AT_PERCISION_MIN, - W_IS_WITHIN_PERCISION_LIMIT, - W_IS_MAX_INTEGER, - W_IS_MIN_INTEGER + IS_POSITIVE_MIN_DIV2, + IS_NEGATIVE_MIN_DIV2, + IS_POSITIVE_SUBNORMAL_MAX, + IS_NEGATIVE_SUBNORMAL_MAX, + IS_POSITIVE_SUBNORMAL_MIN, + IS_NEGATIVE_SUBNORMAL_MIN, + IS_Q_NAN, + IS_S_NAN, + IS_FMV_RAND_RS1, + IS_FCVT_RAND_RS1 } operand_pattens_t; // typedef - end @@ -74,8 +75,7 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; bit more_weight_for_fdiv_fsqrt_gen; // more weight on generating fdiv and fsqrt directed_instr bit init_gpr = (is_zfinx) ? 1 : 0; // initialize gpr registers in stream with rand value bit init_fpr = (is_zfinx) ? 0 : 1; // initialize fpr registers in stream with rand value - bit en_clr_fflags_b4_instr; // clear fflag to prevent residual fflags status from prev f_instr - bit f_clr_fflags_done = 0; + bit en_clr_fflags_af_instr; // clear fflag to prevent residual fflags status of current f_instr // for use_prev_rd_on_next_operands implementation usage - start riscv_reg_t prev_rd; @@ -111,7 +111,7 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; if (is_zfinx) {soft num_of_instr_per_stream inside {[TOTAL_INSTR_ZFINX_TYPE/2 : TOTAL_INSTR_ZFINX_TYPE]};} else {soft num_of_instr_per_stream inside {[TOTAL_INSTR_F_TYPE/2 : TOTAL_INSTR_F_TYPE]};} } else { - if (en_clr_fflags_b4_instr) {soft num_of_instr_per_stream == 50;} + if (en_clr_fflags_af_instr) {soft num_of_instr_per_stream == 50;} else {soft num_of_instr_per_stream == 100;} } num_of_instr_per_stream > 0; @@ -170,7 +170,7 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; use_fp_only_for_directed_instr = 1; // directed instr is fp only use_prev_rd_on_next_operands = 0; use_no_repetitive_instr_per_stream = 0; - en_clr_fflags_b4_instr = 1; + en_clr_fflags_af_instr = 1; endfunction: pre_randomize function void post_randomize(); @@ -226,7 +226,7 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; randomize_gpr_zfinx(instr_zfinx, i); f_use_prev_rd_on_next_operands(.p_instr_zfinx((use_prev_rd_on_next_operands) ? instr_zfinx : null), .idx(i)); if (enable_special_operand_patterns) begin : OVERRIDE_OPERANDS_W_SPECIAL_PATTERNS - manipulate_zfinx_instr_operands(instr_zfinx, i); + rand_fp_special_operands_zfinx(instr_zfinx, i); end instr_list.push_back(instr_zfinx); `uvm_info(_header, $sformatf("\n>>>> instr_zfinx[%s] >>>> \ @@ -245,7 +245,7 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; wa_prevent_store_on_code_space(instr_f); end if (enable_special_operand_patterns) begin : OVERRIDE_OPERANDS_W_SPECIAL_PATTERNS - manipulate_f_instr_operands(instr_f, i); + rand_fp_special_operands(instr_f, i); end instr_list.push_back(instr_f); `uvm_info(_header, $sformatf("\n>>>> instr_f[%s] >>>> \ @@ -262,7 +262,12 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; end // actions after directed instr - act_post_directed_instr(.idx(i)); + act_post_directed_instr( + .p_instr(instr), + .p_instr_zfinx(instr_zfinx), + .p_instr_f(instr_f), + .idx(i) + ); end // for GEN_N_MANIPULATE_INSTR @@ -278,19 +283,41 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; \n>> use_same_instr_per_stream [%0b] \ \n>> use_prev_rd_on_next_operands [%0b] \ \n>> more_weight_for_fdiv_fsqrt_gen [%0b] \ - \n>> en_clr_fflags_b4_instr [%0b] \ ", get_name(), num_of_instr_per_stream, enable_special_operand_patterns, use_fp_only_for_directed_instr, use_no_repetitive_instr_per_stream, use_same_instr_per_stream, use_prev_rd_on_next_operands, - more_weight_for_fdiv_fsqrt_gen, en_clr_fflags_b4_instr + // more_weight_for_fdiv_fsqrt_gen, en_clr_fflags_af_instr + more_weight_for_fdiv_fsqrt_gen ), UVM_NONE); endfunction : print_stream_setting - // clear csr fflags + // clear csr fflags (by through fflags or fcsr) + // condition: reg rs1 must be keep for csr clr purpose only throughout this stream + bit clr_csr_option = $urandom_range(1); + bit clr_csr_init_done = 0; // reduce overhead + riscv_instr_name_t csr_name = INVALID_INSTR; + logic [31:0] csr_rm = $urandom_range(0,4); virtual function void clr_crs_fflags(riscv_reg_t rs1); - directed_csr_access(.instr_name(CSRRC), .rs1(rs1), .csr(12'h001)); - f_clr_fflags_done = 1; + riscv_reg_t i_rs1 = rs1; + logic [31:0] csrrw_val = 0; + + csrrw_val[7:5] = csr_rm; + if (!clr_csr_init_done) begin + if (clr_csr_option) begin `SET_GPR_VALUE(i_rs1,32'h0000_001F); csr_name = CSRRC; end + else begin `SET_GPR_VALUE(i_rs1,csrrw_val); csr_name = CSRRW; end + clr_csr_init_done = 1; + end + if ($urandom_range(1)) directed_csr_access(.instr_name(csr_name), .rs1(i_rs1), .csr(12'h001)); // fflags + else directed_csr_access(.instr_name(csr_name), .rs1(i_rs1), .csr(12'h003)); // fcsr + endfunction : clr_crs_fflags + // set dyamic fm + // condition: this must execute before clr_crs_fflags + virtual function void set_csr_fm(riscv_reg_t rs1); + riscv_reg_t i_rs1 = rs1; + `SET_GPR_VALUE(i_rs1,csr_rm); csr_name = CSRRW; + directed_csr_access(.instr_name(csr_name), .rs1(i_rs1), .csr(12'h002)); // frm + endfunction : set_csr_fm // init all the gpr/fpr based on F/zfinx respectly prior directed stream // reset fpu fflag prior directed stream @@ -322,32 +349,29 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; `SET_FPR_VALUE(i_fpr,i_imm); end end - begin : RESET_FFLAG_TO_ALL_ZEROES - // riscv_reg_t rs1 = T0; - // `SET_GPR_VALUE(local::rs1,32'h0000_001F); - `SET_GPR_VALUE(local::gp_scratch_reg,32'h0000_001F); - clr_crs_fflags(gp_scratch_reg); - end + set_csr_fm(gp_scratch_reg); + clr_crs_fflags(gp_scratch_reg); // note: this must be the last in order endfunction : initialize_regs // for updating the arguments that use in get_rand_instr virtual function void update_current_instr_arg_list(int idx=0); + include_group.delete(); include_group = new[1] ((is_zfinx) ? {RV32ZFINX} : {RV32F}); if (!use_fp_only_for_directed_instr) begin : USE_MIXED_FP_N_OTHERS_INSTR bit select_fp_instr, rand_status; - exclude_instr = new[22] (`EXCLUDE_INSTR_LIST); + exclude_instr = new[33] (`EXCLUDE_INSTR_LIST); if (more_weight_for_fdiv_fsqrt_gen) begin - include_group = new[5] (`RV_DV_ISA); + if ($urandom_range(1)) include_group = new[4] ({include_group, RV32I, RV32M, RV32C}); + else include_group = new[4] ({include_group, RV32I, RV32M, RV32X}); end else begin // put more weight in generating fp instr in directed streams rand_status = std::randomize(select_fp_instr) with {select_fp_instr dist {1:=2, 0:=1};}; assert(rand_status); - if (select_fp_instr) begin - include_group = new[1] ((is_zfinx) ? {RV32ZFINX} : {RV32F}); - end else begin - include_group = new[3] ({RV32I, RV32M, RV32C}); + if (!select_fp_instr) begin + if ($urandom_range(1)) include_group = new[3] ({RV32I, RV32M, RV32C}); + else include_group = new[3] ({RV32I, RV32M, RV32X}); end end @@ -356,10 +380,6 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; // insert additonal instr if there is any prior directed instr virtual function void add_instr_prior_directed_instr(riscv_instr instr, int idx=0); - if (is_fp_instr && en_clr_fflags_b4_instr && !f_clr_fflags_done) begin - clr_crs_fflags(gp_scratch_reg); - f_clr_fflags_done = 1; - end endfunction : add_instr_prior_directed_instr virtual function void update_next_instr_arg_list(riscv_instr prev_instr=null, int idx=0); @@ -541,35 +561,41 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; endfunction: override_instr - // for getting random special pattern and setting + // random pattern for specific scenarios + // note: setting is constraint to meet Imperas coverage virtual function void get_xreg_val_for_rand_pattern(ref int unsigned rs_unsigned, ref int rs_signed, ref operand_pattens_t pattern); - unique case ($urandom_range(0,4)) - 0: begin // percision max - rs_unsigned = 16777216; rs_signed = 16777216; - pattern = W_IS_AT_PERCISION_MAX; - end - 1: begin // percision min - rs_unsigned = 0; rs_signed = -16777216; - pattern = W_IS_AT_PERCISION_MIN; - end - 2: begin // within percision limit - rs_unsigned = $urandom_range(0, 16777216); - rs_signed = ($urandom_range(1)) ? (int'(rs_unsigned)) : (int'(rs_unsigned) * (-1)); // range from -16777216 till 16777216 - pattern = W_IS_WITHIN_PERCISION_LIMIT; - end - 3: begin // max integer - rs_unsigned = 32'hFFFF_FFFF; rs_signed = 32'h7FFF_FFFF; - pattern = W_IS_MAX_INTEGER; - end - 4: begin // min integer - rs_unsigned = 32'h0; rs_signed = 32'h8000_0000; - pattern = W_IS_MIN_INTEGER; - end - endcase + int unsigned rand_case; + + if (pattern == IS_FCVT_RAND_RS1) rand_case = $urandom_range(0,3); + if (pattern == IS_FMV_RAND_RS1) rand_case = $urandom_range(0,16); + if (pattern == IS_FCVT_RAND_RS1 || pattern == IS_FMV_RAND_RS1) begin + // valid sign int: from -(2e31) till (2e31)-1 + // valid unsign int: from 0 till (2e32)-1 + unique case (rand_case) + 0: rs_signed = 32'h0; // 0 + 1: rs_signed = 32'h8000_0000; // -(2e31) or 2e31 + 2: rs_signed = 32'h7FFF_FFFF; // (2e31)-1 + 3: rs_signed = 32'hFFFF_FFFF; // 1 or (2e32)-1 + 4: rs_signed = 32'h0080_0000; + 5: rs_signed = 32'h8080_0000; + 6: rs_signed = 32'h0040_0000; + 7: rs_signed = 32'h8040_0000; + 8: rs_signed = 32'h7F7F_FFFF; + 9: rs_signed = 32'hFF7F_FFFF; + 10: rs_signed = 32'h007F_FFFF; + 11: rs_signed = 32'h807F_FFFF; + 12: rs_signed = 32'h1; + 13: rs_signed = 32'h8000_0001; + 14: rs_signed = 32'h7F80_0000; + 15: rs_signed = 32'hFF80_0000; + 16: rs_signed = $urandom_range(32'h7FC0_0000, 32'h7FFF_FFFF); + endcase + end + rs_unsigned = rs_signed; endfunction : get_xreg_val_for_rand_pattern // for manipulating zfinx instr operands - virtual function void manipulate_zfinx_instr_operands(riscv_fp_in_x_regs_instr instr=null, int idx=0); + virtual function void rand_fp_special_operands_zfinx(riscv_fp_in_x_regs_instr instr=null, int idx=0); bit [31:0] m_operand_a, m_operand_b, m_operand_c; operand_pattens_t m_operand_a_pattern, m_operand_b_pattern, m_operand_c_pattern; @@ -578,62 +604,69 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; m_operand_b = operand_b[idx]; m_operand_b_pattern = operand_b_pattern[idx]; m_operand_c = operand_c[idx]; m_operand_c_pattern = operand_c_pattern[idx]; - if (!(instr.instr_name inside {FCVT_S_W, FCVT_S_WU})) begin + if (!(instr.instr_name inside {FCVT_S_W, FCVT_S_WU})) begin : FOR_SRC_IS_FS `MANIPULATE_GPR_OPERANDS(rs1,m_operand_a); `MANIPULATE_GPR_OPERANDS(rs2,m_operand_b); `MANIPULATE_GPR_OPERANDS(rs3,m_operand_c); end - else begin : FOR_CVT_FROM_INT_TO_FP + else if ((instr.instr_name inside {FCVT_S_W, FCVT_S_WU})) begin : FOR_SRC_IS_RS if (instr.has_rs1 && operand_a_pattern[idx] != IS_RAND) begin int unsigned rs1_unsigned; int rs1_signed; + m_operand_a_pattern = IS_FCVT_RAND_RS1; get_xreg_val_for_rand_pattern( .rs_unsigned (rs1_unsigned), .rs_signed (rs1_signed), .pattern (m_operand_a_pattern) ); - if (instr.instr_name == FCVT_S_WU) m_operand_a = rs1_unsigned; - else m_operand_a = rs1_signed; + m_operand_a = rs1_signed; `MANIPULATE_GPR_OPERANDS(rs1, m_operand_a); end - end // FOR_CVT_FROM_INT_TO_FP + end + else begin + `uvm_fatal(_header, $sformatf("[rand_fp_special_operands_zfinx] Invalid")); + end - endfunction: manipulate_zfinx_instr_operands + endfunction: rand_fp_special_operands_zfinx // for manipulating f instr operands - virtual function void manipulate_f_instr_operands(riscv_floating_point_instr instr=null, int idx=0); + virtual function void rand_fp_special_operands(riscv_floating_point_instr instr=null, int idx=0); bit [31:0] m_operand_a, m_operand_b, m_operand_c; operand_pattens_t m_operand_a_pattern, m_operand_b_pattern, m_operand_c_pattern; riscv_reg_t imm_rd; - void'(std::randomize(imm_rd) with {!(imm_rd inside {cfg.reserved_regs, reserved_rd, instr.rs1, instr.rs2, instr.rd, ZERO}); }); + void'(std::randomize(imm_rd) with {!(imm_rd inside {cfg.reserved_regs, reserved_rd, instr.rs1, instr.rs2, instr.rd, gp_scratch_reg, ZERO}); }); // for MANIPULATE_FPR_OPERANDS m_operand_a = operand_a[idx]; m_operand_a_pattern = operand_a_pattern[idx]; m_operand_b = operand_b[idx]; m_operand_b_pattern = operand_b_pattern[idx]; m_operand_c = operand_c[idx]; m_operand_c_pattern = operand_c_pattern[idx]; - if (!(instr.instr_name inside {FCVT_S_W, FCVT_S_WU})) begin + if (!(instr.instr_name inside {FCVT_S_W, FCVT_S_WU, FMV_W_X})) begin : FOR_SRC_IS_FS `MANIPULATE_FPR_OPERANDS(fs1,m_operand_a); `MANIPULATE_FPR_OPERANDS(fs2,m_operand_b); `MANIPULATE_FPR_OPERANDS(fs3,m_operand_c); end - else begin : FOR_CVT_FROM_INT_TO_FP + else if ((instr.instr_name inside {FCVT_S_W, FCVT_S_WU, FMV_W_X})) begin : FOR_SRC_IS_RS if (instr.has_rs1 && operand_a_pattern[idx] != IS_RAND) begin int unsigned rs1_unsigned; int rs1_signed; + if (instr.instr_name == FMV_W_X) m_operand_a_pattern = IS_FMV_RAND_RS1; + else m_operand_a_pattern = IS_FCVT_RAND_RS1; get_xreg_val_for_rand_pattern( .rs_unsigned (rs1_unsigned), .rs_signed (rs1_signed), .pattern (m_operand_a_pattern) ); - if (instr.instr_name == FCVT_S_WU) m_operand_a = rs1_unsigned; - else m_operand_a = rs1_signed; + m_operand_a = rs1_signed; `MANIPULATE_GPR_OPERANDS(rs1, m_operand_a); end - end // FOR_CVT_FROM_INT_TO_FP + end + else begin + `uvm_fatal(_header, $sformatf("[rand_fp_special_operands] Invalid")); + end - endfunction: manipulate_f_instr_operands + endfunction: rand_fp_special_operands // placeholder for post actions after directed instr virtual function void act_post_directed_instr( @@ -642,7 +675,8 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; riscv_floating_point_instr p_instr_f=null, int idx=0); if (is_fp_instr) begin - f_clr_fflags_done = 0; + if (en_clr_fflags_af_instr) + clr_crs_fflags(gp_scratch_reg); end endfunction: act_post_directed_instr @@ -819,7 +853,6 @@ class cv32e40p_fp_n_mixed_instr_stream extends cv32e40p_float_zfinx_base_instr_s function void pre_randomize(); super.pre_randomize(); use_fp_only_for_directed_instr = 0; // directed instr is mixtured of supported isa - en_clr_fflags_b4_instr = 0; endfunction: pre_randomize endclass: cv32e40p_fp_n_mixed_instr_stream @@ -857,7 +890,7 @@ class cv32e40p_fp_w_special_operands_instr_stream extends cv32e40p_float_zfinx_b // to define exclude list for this stream class virtual function void update_current_instr_arg_list(int idx=0); super.update_current_instr_arg_list(idx); - // TODO: should test all rather just focus on specific instrs as per verifplan. although others are covered in onespin? + // note: it should test all rather just focus on specific instrs as per verifplan. ease for Imperas coverage analysis // if (!use_no_repetitive_instr_per_stream && !use_same_instr_per_stream) begin // exclude_instr = new[exclude_instr.size() + 12] ( // {exclude_instr, FADD_S, FSUB_S, FMIN_S, FMAX_S, FSGNJ_S, FSGNJN_S, FSGNJX_S, FMV_W_X, FEQ_S, FLT_S, FLE_S, FCLASS_S}); @@ -875,11 +908,15 @@ class cv32e40p_fp_w_prev_rd_as_operand_instr_stream extends cv32e40p_float_zfinx `uvm_object_utils(cv32e40p_fp_w_prev_rd_as_operand_instr_stream) `uvm_object_new + constraint ovr_c_others { + num_of_instr_per_stream == 20; + } + function void pre_randomize(); super.pre_randomize(); use_prev_rd_on_next_operands = 1; use_fp_only_for_directed_instr = 0; - en_clr_fflags_b4_instr = 0; + en_clr_fflags_af_instr = 0; endfunction: pre_randomize // to define exclude list for this stream class @@ -924,7 +961,6 @@ class cv32e40p_constraint_mc_fp_instr_stream extends cv32e40p_float_zfinx_base_i // cycle through all possible mc instrs for selected directed fp instr per stream use_fp_only_for_directed_instr = 1; use_same_instr_per_stream = 1; - en_clr_fflags_b4_instr = 0; assert (use_fp_only_for_directed_instr && use_same_instr_per_stream); endfunction: pre_randomize @@ -933,8 +969,9 @@ class cv32e40p_constraint_mc_fp_instr_stream extends cv32e40p_float_zfinx_base_i riscv_fp_in_x_regs_instr p_instr_zfinx=null, riscv_floating_point_instr p_instr_f=null, int idx=0); + super.act_post_directed_instr(); // put some random NOP before next mc fp iteration - insert_nop_instr($urandom_range(2,3)); + insert_nop_instr($urandom_range(1,2)); endfunction: act_post_directed_instr // stream implementation to insert mc fp instr @@ -961,7 +998,7 @@ class cv32e40p_constraint_mc_fp_instr_stream extends cv32e40p_float_zfinx_base_i else begin `DV_CHECK_FATAL($cast(mc_instr_f, mc_instr), "Cast to instr_f failed!"); randomize_fpr(mc_instr_f, idx); - if (mc_instr_f.instr_name inside {FSW, SB, SH, SW}) begin: SPECIAL_HANDLING_FOR_FLW + if (mc_instr_f.instr_name inside {FSW, SB, SH, SW}) begin: SPECIAL_HANDLING_FOR_STORE wa_prevent_store_on_code_space(mc_instr_f); end update_mc_instr_latency(mc_instr_f); @@ -1129,7 +1166,6 @@ class cv32e40p_fp_operand_forwarding_instr_stream extends cv32e40p_float_zfinx_b super.pre_randomize(); use_fp_only_for_directed_instr = 0; num_of_instr_per_block = 10; - en_clr_fflags_b4_instr = 0; assert (num_of_instr_per_block != 0 && num_of_instr_per_block%10 == 0); endfunction: pre_randomize @@ -1146,8 +1182,8 @@ class cv32e40p_fp_operand_forwarding_instr_stream extends cv32e40p_float_zfinx_b endfunction : print_stream_setting // to define exclude list for this stream class - virtual function void update_directed_instr_arg_list(int idx=0); - exclude_instr = new[22] (`EXCLUDE_INSTR_LIST); + virtual function void update_current_instr_arg_list(int idx=0); + exclude_instr = new[33] (`EXCLUDE_INSTR_LIST); // always exclude all store instr to prevent from overriding the code space; exclude_instr = new[exclude_instr.size() + 4] ({exclude_instr, FSW, SB, SH, SW}); // always exclude RV32C because it only uses 8 common gpr. We cover > 8 gpr here @@ -1160,10 +1196,11 @@ class cv32e40p_fp_operand_forwarding_instr_stream extends cv32e40p_float_zfinx_b else include_instr.delete(); end else begin - include_group = new[2] ({RV32I, RV32M}); + if ($urandom_range(1)) include_group = new[3] ({RV32I, RV32M, RV32C}); + else include_group = new[3] ({RV32I, RV32M, RV32X}); include_instr.delete(); end - endfunction: update_directed_instr_arg_list + endfunction: update_current_instr_arg_list virtual function void act_post_directed_instr( riscv_instr p_instr=null, @@ -1269,7 +1306,7 @@ class cv32e40p_fp_operand_forwarding_instr_stream extends cv32e40p_float_zfinx_b // $display("instr_order_per_block[shuffle] is %p", instr_order_per_block); end - update_directed_instr_arg_list(i % num_of_instr_per_block); + update_current_instr_arg_list(i % num_of_instr_per_block); loop_cnt = 0; do begin : GEN_INSTR_PER_BLOCK if (loop_cnt == loop_limit) begin `uvm_fatal(_header, $sformatf("loop_limit reached [GEN_INSTR_PER_BLOCK]")) end; @@ -1326,6 +1363,7 @@ class cv32e40p_fp_operand_forwarding_instr_stream extends cv32e40p_float_zfinx_b instr_list.push_back(i_instr_list[j]); instr_list[$].comment = {instr_list[$].comment, $sformatf(" Inserted %0s - blk_idx[%0d]", get_name(), j)}; end + clr_crs_fflags(gp_scratch_reg); end // POST_PROCESS_BLOCK end // for GEN_N_MANIPULATE_INSTR @@ -1334,72 +1372,4 @@ class cv32e40p_fp_operand_forwarding_instr_stream extends cv32e40p_float_zfinx_b endclass: cv32e40p_fp_operand_forwarding_instr_stream - -// directed test for below scenarios (for zfinx=0) -// scenario_1 - fp isntr cause FS changed to dirty state following by csrr on mstatus -// scenario_2 - csrr fflags after any fp instr that have chances to alter fflags -class cv32e40p_fp_followed_by_csrr_instr_stream extends cv32e40p_fp_w_special_operands_instr_stream; - - `uvm_object_utils(cv32e40p_fp_followed_by_csrr_instr_stream) - `uvm_object_new - - constraint ovr_c_others { - num_of_instr_per_stream == 5; - } - - constraint ovr_c_operand_pattern { - foreach (operand_a_pattern[i]) { - operand_a_pattern[i] dist {IS_RAND := 2, IS_POSITIVE_ZERO := 1, IS_NEGATIVE_ZERO := 1, IS_POSITIVE_MAX := 1, IS_NEGATIVE_MAX := 1, IS_POSITIVE_MIN := 1, IS_NEGATIVE_MIN := 1}; - operand_b_pattern[i] dist {IS_RAND := 2, IS_POSITIVE_ZERO := 1, IS_NEGATIVE_ZERO := 1, IS_POSITIVE_MAX := 1, IS_NEGATIVE_MAX := 1, IS_POSITIVE_MIN := 1, IS_NEGATIVE_MIN := 1}; - operand_c_pattern[i] dist {IS_RAND := 2, IS_POSITIVE_ZERO := 1, IS_NEGATIVE_ZERO := 1, IS_POSITIVE_MAX := 1, IS_NEGATIVE_MAX := 1, IS_POSITIVE_MIN := 1, IS_NEGATIVE_MIN := 1}; - } - } - - function void pre_randomize(); - super.pre_randomize(); - en_clr_fflags_b4_instr = 0; - include_instr = new[3] ({FMUL_S, FDIV_S, FSQRT_S}); // these instr can easily causes fflag get updated - if (is_zfinx) begin - `uvm_fatal(_header, $sformatf("This test is for FPU with zfinx==0")) - end - endfunction: pre_randomize - - // scenario_1 - virtual function void initialize_regs(); - riscv_reg_t rs1 = T0; - riscv_reg_t rd = T1; - riscv_instr instr; - riscv_floating_point_instr instr_f; - // set mstatus.FS from dirty->initial - `SET_GPR_VALUE(local::gp_scratch_reg,32'h0000_4000); - directed_csr_access(.instr_name(CSRRC), .rs1(gp_scratch_reg), .csr(12'h300)); - insert_nop_instr(2); - // insert any fp instr - instr = new riscv_instr::get_rand_instr( - .include_instr({FMV_W_X}) // todo: maybe need to put some which affect by latency param / fdiv - ); - `DV_CHECK_FATAL($cast(instr_f, instr), "Cast to instr_f failed!"); - randomize_fpr(instr_f); - instr_list.push_back(instr_f); - // csrr mstatus - directed_csr_access(.instr_name(CSRRS), .rd(rd), .csr(12'h300)); - insert_nop_instr(2); - - super.initialize_regs(); - endfunction : initialize_regs - - // scenario_2 - virtual function void act_post_directed_instr( - riscv_instr p_instr=null, - riscv_fp_in_x_regs_instr p_instr_zfinx=null, - riscv_floating_point_instr p_instr_f=null, - int idx=0); - riscv_reg_t rd; - void'(std::randomize(rd) with {!(rd inside {avail_gp_regs[idx]});}); - directed_csr_access(.instr_name(CSRRS), .rd(rd), .csr(12'h001), .idx(idx)); - endfunction: act_post_directed_instr - -endclass: cv32e40p_fp_followed_by_csrr_instr_stream - - // ALL FP STREAM CLASSESS - end diff --git a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib_defines.sv b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib_defines.sv index 56ce0e63a0..ff44b9c34b 100644 --- a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib_defines.sv +++ b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib_defines.sv @@ -24,12 +24,15 @@ soft operand_``IDX``_pattern.size() == num_of_instr_per_stream;\ foreach (operand_``IDX``_pattern[i]) {\ if (enable_special_operand_patterns) {\ - soft operand_``IDX``_pattern[i] dist { IS_RAND := 8, IS_Q_NAN := 4, IS_S_NAN := 4, \ - IS_POSITIVE_ZERO := 4, IS_NEGATIVE_ZERO := 4, \ - IS_POSITIVE_INFINITY := 4, IS_NEGATIVE_INFINITY := 4, \ - IS_POSITIVE_MAX := 2, IS_NEGATIVE_MAX := 2, \ - IS_POSITIVE_MIN := 2, IS_NEGATIVE_MIN := 2, \ - IS_POSITIVE_SUBNORMAL := 4, IS_NEGATIVE_SUBNORMAL := 4 };\ + soft operand_``IDX``_pattern[i] dist { IS_RAND := 6, \ + IS_Q_NAN := 4, IS_S_NAN := 4, \ + IS_POSITIVE_ZERO := 4, IS_NEGATIVE_ZERO := 4, \ + IS_POSITIVE_INFINITY := 4, IS_NEGATIVE_INFINITY := 4, \ + IS_POSITIVE_MAX := 4, IS_NEGATIVE_MAX := 4, \ + IS_POSITIVE_MIN := 4, IS_NEGATIVE_MIN := 4, \ + IS_POSITIVE_MIN_DIV2 := 4, IS_NEGATIVE_MIN_DIV2 := 4, \ + IS_POSITIVE_SUBNORMAL_MAX := 4, IS_NEGATIVE_SUBNORMAL_MAX := 4, \ + IS_POSITIVE_SUBNORMAL_MIN := 4, IS_NEGATIVE_SUBNORMAL_MIN := 4 };\ } else {\ soft operand_``IDX``_pattern[i] == IS_RAND;\ }\ @@ -62,22 +65,34 @@ sign_``IDX``[i] == 1'b1; exp_``IDX``[i] == 8'hFE; mantissa_``IDX``[i][22:0] == 23'h7FFFFF;\ }\ if (operand_``IDX``_pattern[i] == IS_POSITIVE_MIN) {\ - sign_``IDX``[i] == 1'b0; exp_``IDX``[i] == 8'h00; mantissa_``IDX``[i][22:0] == 23'h1;\ + sign_``IDX``[i] == 1'b0; exp_``IDX``[i] == 8'h01; mantissa_``IDX``[i][22:0] == 23'h0;\ }\ if (operand_``IDX``_pattern[i] == IS_NEGATIVE_MIN) {\ - sign_``IDX``[i] == 1'b1; exp_``IDX``[i] == 8'h00; mantissa_``IDX``[i][22:0] == 23'h1;\ + sign_``IDX``[i] == 1'b1; exp_``IDX``[i] == 8'h01; mantissa_``IDX``[i][22:0] == 23'h0;\ + }\ + if (operand_``IDX``_pattern[i] == IS_POSITIVE_MIN_DIV2) {\ + sign_``IDX``[i] == 1'b0; exp_``IDX``[i] == 8'h00; mantissa_``IDX``[i][22:0] == 23'h400000;\ + }\ + if (operand_``IDX``_pattern[i] == IS_NEGATIVE_MIN_DIV2) {\ + sign_``IDX``[i] == 1'b1; exp_``IDX``[i] == 8'h00; mantissa_``IDX``[i][22:0] == 23'h400000;\ }\ - if (operand_``IDX``_pattern[i] == IS_POSITIVE_SUBNORMAL) {\ - sign_``IDX``[i] == 1'b0; exp_``IDX``[i] == 8'h00; mantissa_``IDX``[i][22:0] != 0;\ + if (operand_``IDX``_pattern[i] == IS_POSITIVE_SUBNORMAL_MAX) {\ + sign_``IDX``[i] == 1'b0; exp_``IDX``[i] == 8'h00; mantissa_``IDX``[i][22:0] == 23'h7FFFFF;\ }\ - if (operand_``IDX``_pattern[i] == IS_NEGATIVE_SUBNORMAL) {\ - sign_``IDX``[i] == 1'b1; exp_``IDX``[i] == 8'h00; mantissa_``IDX``[i][22:0] != 0;\ + if (operand_``IDX``_pattern[i] == IS_NEGATIVE_SUBNORMAL_MAX) {\ + sign_``IDX``[i] == 1'b1; exp_``IDX``[i] == 8'h00; mantissa_``IDX``[i][22:0] == 23'h7FFFFF;\ + }\ + if (operand_``IDX``_pattern[i] == IS_POSITIVE_SUBNORMAL_MIN) {\ + sign_``IDX``[i] == 1'b0; exp_``IDX``[i] == 8'h00; mantissa_``IDX``[i][22:0] == 23'h1;\ + }\ + if (operand_``IDX``_pattern[i] == IS_NEGATIVE_SUBNORMAL_MIN) {\ + sign_``IDX``[i] == 1'b1; exp_``IDX``[i] == 8'h00; mantissa_``IDX``[i][22:0] == 23'h1;\ }\ if (operand_``IDX``_pattern[i] == IS_Q_NAN) {\ - sign_``IDX``[i] == 1'b1; exp_``IDX``[i] == 8'hFF; mantissa_``IDX``[i][22] == 1'b1;\ + sign_``IDX``[i] == 1'b0; exp_``IDX``[i] == 8'hFF; mantissa_``IDX``[i][22] == 1'b1;\ }\ if (operand_``IDX``_pattern[i] == IS_S_NAN) {\ - sign_``IDX``[i] == 1'b1; exp_``IDX``[i] == 8'hFF; mantissa_``IDX``[i][22] == 1'b0; mantissa_``IDX``[i][21:0] != 0;\ + sign_``IDX``[i] == 1'b0; exp_``IDX``[i] == 8'hFF; mantissa_``IDX``[i][22] == 1'b0; mantissa_``IDX``[i][21:0] != 0;\ }\ operand_``IDX[i] == {sign_``IDX``[i], exp_``IDX``[i], mantissa_``IDX``[i]};\ solve operand_``IDX``_pattern[i] before sign_``IDX``[i];\ @@ -168,10 +183,11 @@ instr_list[$].comment = {instr_list[$].comment, $sformatf(`" [``OPERAND`` - %s - 32'h%8h] `", ``OPERAND``_pattern.name(), ``OPERAND``)};\ end - // 22 always exclude list within fp stream - `define EXCLUDE_INSTR_LIST {JAL, JALR, BEQ, BNE, BLT, BGE, BLTU, BGEU, ECALL, EBREAK, \ - DRET, MRET, URET, SRET, WFI, C_EBREAK, C_BEQZ, C_BNEZ, C_J, C_JAL, \ - C_JR, C_JALR} + // 22 always exclude list within fp stream; 11 are related to hw-loop (total 33) + `define EXCLUDE_INSTR_LIST {JAL, JALR, BEQ, BNE, BLT, BGE, BLTU, BGEU, ECALL, EBREAK, \ + DRET, MRET, URET, SRET, WFI, C_EBREAK, C_BEQZ, C_BNEZ, C_J, C_JAL, \ + C_JR, C_JALR, \ + CV_START, CV_STARTI, CV_END, CV_ENDI, CV_COUNT, CV_COUNTI, CV_SETUP, CV_SETUPI, CV_ELW, CV_BEQIMM, CV_BNEIMM} // refer Table 6-1 user manual `define RV32I_INT_COMP_INSTR_LIST {ADD, ADDI, SUB, LUI, AUIPC, SLL, SLLI, SRL, SRLI, SRA, SRAI, \ diff --git a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_pulp_hwloop_instr_lib.sv b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_pulp_hwloop_instr_lib.sv index 18a9c20494..dced7e6b06 100644 --- a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_pulp_hwloop_instr_lib.sv +++ b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_pulp_hwloop_instr_lib.sv @@ -102,10 +102,21 @@ class cv32e40p_xpulp_hwloop_base_stream extends cv32e40p_xpulp_rand_stream; cv32e40p_instr hwloop_count_instr[2]; static int stream_count = 0; + string start_label_s; + string end_label_s; riscv_instr_category_t xpulp_exclude_category[]; `uvm_object_utils_begin(cv32e40p_xpulp_hwloop_base_stream) + `uvm_field_int(num_of_xpulp_instr, UVM_DEFAULT) + `uvm_field_int(num_of_riscv_instr, UVM_DEFAULT) + `uvm_field_int(num_of_avail_regs, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_reg_t,cv32e40p_avail_regs, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_reg_t,cv32e40p_exclude_regs, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_instr_name_t,xpulp_exclude_instr, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_instr_name_t,riscv_exclude_common_instr, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_instr_name_t,riscv_exclude_instr, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_instr_group_t,riscv_exclude_group, UVM_DEFAULT) `uvm_field_int(num_loops_active, UVM_DEFAULT) `uvm_field_int(gen_nested_loop, UVM_DEFAULT) `uvm_field_sarray_int(use_setup_inst, UVM_DEFAULT) @@ -135,8 +146,7 @@ class cv32e40p_xpulp_hwloop_base_stream extends cv32e40p_xpulp_rand_stream; } constraint avail_regs_pulp_instr_c { - num_of_avail_regs inside {[10:20]}; - num_of_reserved_regs == 5; + num_of_avail_regs inside {[10:19]}; } constraint gen_hwloop_count_c { @@ -254,7 +264,11 @@ class cv32e40p_xpulp_hwloop_base_stream extends cv32e40p_xpulp_rand_stream; endfunction : pre_randomize function void post_randomize(); - uvm_default_printer.knobs.begin_elements = -1; + + if((cv32e40p_exclude_regs.size() < 2) || (cv32e40p_exclude_regs.size() > 25)) begin + `uvm_fatal(this.get_type_name(), "cv32e40p_exclude_regs out of range") + end + this.print(); gen_xpulp_hwloop_control_instr(); endfunction : post_randomize @@ -307,8 +321,6 @@ class cv32e40p_xpulp_hwloop_base_stream extends cv32e40p_xpulp_rand_stream; riscv_instr hwloop_instr_list[$]; int unsigned num_rem_hwloop1_instr; //indicates num of hwloop_1 body instructions after hwloop_0 body for nested hwloops string label_s; - string start_label_s; - string end_label_s; num_instr_cv_start_to_loop_start_label[0] = num_fill_instr_loop_ctrl_to_loop_start[0] + 2;//TODO: can be randomized? num_instr_cv_start_to_loop_start_label[1] = num_fill_instr_loop_ctrl_to_loop_start[1] + 2;//TODO: can be randomized? @@ -346,6 +358,7 @@ class cv32e40p_xpulp_hwloop_base_stream extends cv32e40p_xpulp_rand_stream; std::randomize(hwloop_avail_regs) with { unique {hwloop_avail_regs}; foreach(hwloop_avail_regs[i]) { !(hwloop_avail_regs[i] inside {ZERO, RA, SP, GP, TP}); + !(hwloop_avail_regs[i] inside {cfg.reserved_regs}); } }; @@ -507,6 +520,7 @@ class cv32e40p_xpulp_hwloop_base_stream extends cv32e40p_xpulp_rand_stream; std::randomize(hwloop_avail_regs) with { unique {hwloop_avail_regs}; foreach(hwloop_avail_regs[i]) { !(hwloop_avail_regs[i] inside {ZERO, RA, SP, GP, TP}); + !(hwloop_avail_regs[i] inside {cfg.reserved_regs}); } }; @@ -874,18 +888,23 @@ class cv32e40p_xpulp_hwloop_base_stream extends cv32e40p_xpulp_rand_stream; bit no_compressed=1, bit no_fence=1); - riscv_instr instr; - int unsigned i; + riscv_instr instr; + riscv_fp_in_x_regs_instr zfinx_instr; + int unsigned i; + riscv_instr_group_t riscv_exclude_xpulp[]; + int rv32_ins, pulp_ins; + + riscv_exclude_instr = {riscv_exclude_common_instr}; //use cfg for ebreak if(cfg.no_ebreak) riscv_exclude_instr = {riscv_exclude_instr, EBREAK, C_EBREAK}; if(no_branch) - riscv_exclude_instr = {riscv_exclude_instr, BEQ, BNE, BLT, BGE, BLTU, BGEU, C_BEQZ, C_BNEZ}; + riscv_exclude_instr = {riscv_exclude_instr, BEQ, BNE, BLT, BGE, BLTU, BGEU, C_BEQZ, C_BNEZ, CV_BEQIMM, CV_BNEIMM}; if(no_compressed) - riscv_exclude_group = {riscv_exclude_group, RV32C}; + riscv_exclude_group = {riscv_exclude_group, RV32C, RV32FC}; if(no_fence) riscv_exclude_instr = {riscv_exclude_instr, FENCE, FENCE_I}; @@ -899,6 +918,10 @@ class cv32e40p_xpulp_hwloop_base_stream extends cv32e40p_xpulp_rand_stream; $sformatf("Too many hwloop instr. num_rand_instr = %0d",num_rand_instr)) end + riscv_exclude_xpulp = {riscv_exclude_group, RV32X}; + rv32_ins = $urandom_range(0,3); + pulp_ins = $urandom_range(0,3); + i = 0; while (i < num_rand_instr) begin //Create and Randomize array for avail_regs each time to ensure randomization @@ -906,16 +929,40 @@ class cv32e40p_xpulp_hwloop_base_stream extends cv32e40p_xpulp_rand_stream; randomize_avail_regs(); instr = riscv_instr::type_id::create($sformatf("instr_%0d", i)); - instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), - .exclude_group(riscv_exclude_group)); - //randomize GPRs for each instruction - randomize_gpr(instr); + if((rv32_ins + pulp_ins) == 0) begin + instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), + .exclude_group(riscv_exclude_group)); + end + + randcase + pulp_ins: begin + instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), + .exclude_group(riscv_exclude_group)); + end + + rv32_ins: begin + instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), + .exclude_group(riscv_exclude_xpulp)); + end + endcase //randomize immediates for each instruction randomize_riscv_instr_imm(instr); - instr_list.push_back(instr); + if(instr.group != RV32ZFINX) begin + //randomize GPRs for each instruction + randomize_gpr(instr); + store_instr_gpr_handling(instr); + instr_list.push_back(instr); + end else begin + zfinx_instr = riscv_fp_in_x_regs_instr::type_id::create($sformatf("zfinx_instr_%0d", i)); + `DV_CHECK_FATAL($cast(zfinx_instr, instr), "Cast to zfinx instruction type failed!"); + //randomize GPRs for each instruction + randomize_zfinx_gpr(zfinx_instr, cv32e40p_zfinx_regs); + instr_list.push_back(zfinx_instr); + end + i++; end @@ -926,37 +973,71 @@ class cv32e40p_xpulp_hwloop_base_stream extends cv32e40p_xpulp_rand_stream; bit no_branch=1, bit no_compressed=1, bit no_fence=1); - riscv_instr instr; - cv32e40p_instr cv32_instr; + riscv_instr instr; + cv32e40p_instr cv32_instr; + riscv_fp_in_x_regs_instr zfinx_instr; + riscv_instr_group_t riscv_exclude_xpulp[]; + int rv32_ins, pulp_ins; + + riscv_exclude_instr = {riscv_exclude_common_instr}; //use cfg for ebreak if(cfg.no_ebreak) riscv_exclude_instr = {riscv_exclude_instr, EBREAK, C_EBREAK}; if(no_branch) - riscv_exclude_instr = {riscv_exclude_instr, BEQ, BNE, BLT, BGE, BLTU, BGEU, C_BEQZ, C_BNEZ}; + riscv_exclude_instr = {riscv_exclude_instr, BEQ, BNE, BLT, BGE, BLTU, BGEU, C_BEQZ, C_BNEZ, CV_BEQIMM, CV_BNEIMM}; if(no_compressed) - riscv_exclude_group = {riscv_exclude_group, RV32C}; + riscv_exclude_group = {riscv_exclude_group, RV32C, RV32FC}; if(no_fence) riscv_exclude_instr = {riscv_exclude_instr, FENCE, FENCE_I}; + riscv_exclude_xpulp = {riscv_exclude_group, RV32X}; + rv32_ins = $urandom_range(0,2); + pulp_ins = $urandom_range(0,2); + //Create and Randomize array for avail_regs each time to ensure randomization avail_regs = new[num_of_avail_regs]; randomize_avail_regs(); instr = riscv_instr::type_id::create($sformatf("instr_%0s", label_str)); - instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), - .exclude_group(riscv_exclude_group)); - //randomize GPRs for each instruction - randomize_gpr(instr); + if((rv32_ins + pulp_ins) == 0) begin + instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), + .exclude_group(riscv_exclude_group)); + end + + randcase + pulp_ins: begin + instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), + .exclude_group(riscv_exclude_group)); + end + + rv32_ins: begin + instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), + .exclude_group(riscv_exclude_xpulp)); + end + endcase + //randomize immediates for each instruction randomize_riscv_instr_imm(instr); instr.has_label=1; instr.label = label_str; - instr_list.push_back(instr); + + if(instr.group != RV32ZFINX) begin + //randomize GPRs for each instruction + randomize_gpr(instr); + store_instr_gpr_handling(instr); + instr_list.push_back(instr); + end else begin + zfinx_instr = riscv_fp_in_x_regs_instr::type_id::create($sformatf("zfinx_instr_%0s", label_str)); + `DV_CHECK_FATAL($cast(zfinx_instr, instr), "Cast to zfinx instruction type failed!"); + //randomize GPRs for each instruction + randomize_zfinx_gpr(zfinx_instr, cv32e40p_zfinx_regs); + instr_list.push_back(zfinx_instr); + end endfunction @@ -1302,7 +1383,7 @@ class cv32e40p_xpulp_hwloop_isa_stress_stream extends cv32e40p_xpulp_hwloop_base endfunction : pre_randomize function void post_randomize(); - cv32e40p_exclude_regs = {cv32e40p_exclude_regs,cv32e40p_reserved_regs}; + cv32e40p_exclude_regs = {cv32e40p_exclude_regs, cfg.reserved_regs}; super.post_randomize(); this.print(); endfunction : post_randomize @@ -1312,19 +1393,22 @@ class cv32e40p_xpulp_hwloop_isa_stress_stream extends cv32e40p_xpulp_hwloop_base bit no_compressed=1, bit no_fence=1); - riscv_instr instr; - cv32e40p_instr cv32_instr; - int unsigned i; + riscv_instr instr; + cv32e40p_instr cv32_instr; + riscv_fp_in_x_regs_instr zfinx_instr; + int unsigned i; + + riscv_exclude_instr = {riscv_exclude_common_instr}; //use cfg for ebreak if(cfg.no_ebreak) riscv_exclude_instr = {riscv_exclude_instr, EBREAK, C_EBREAK}; if(no_branch) - riscv_exclude_instr = {riscv_exclude_instr, BEQ, BNE, BLT, BGE, BLTU, BGEU, C_BEQZ, C_BNEZ}; + riscv_exclude_instr = {riscv_exclude_instr, BEQ, BNE, BLT, BGE, BLTU, BGEU, C_BEQZ, C_BNEZ, CV_BEQIMM, CV_BNEIMM}; if(no_compressed) - riscv_exclude_group = {riscv_exclude_group, RV32C}; + riscv_exclude_group = {riscv_exclude_group, RV32C, RV32FC}; if(no_fence) riscv_exclude_instr = {riscv_exclude_instr, FENCE, FENCE_I}; @@ -1349,7 +1433,7 @@ class cv32e40p_xpulp_hwloop_isa_stress_stream extends cv32e40p_xpulp_hwloop_base cv32e40p_avail_regs = new[num_of_avail_regs]; std::randomize(cv32e40p_avail_regs) with { foreach(cv32e40p_avail_regs[i]) { - !(cv32e40p_avail_regs[i] inside {cv32e40p_exclude_regs}); + !(cv32e40p_avail_regs[i] inside {cv32e40p_exclude_regs, reserved_rd}); } }; @@ -1361,11 +1445,18 @@ class cv32e40p_xpulp_hwloop_isa_stress_stream extends cv32e40p_xpulp_hwloop_base //randomize GPRs and immediates for each instruction if(instr.group != RV32X) begin - randomize_gpr(instr); randomize_riscv_instr_imm(instr); - instr_list.push_back(instr); - end - else begin + if(instr.group != RV32ZFINX) begin + randomize_gpr(instr); + store_instr_gpr_handling(instr); + instr_list.push_back(instr); + end else begin + zfinx_instr = riscv_fp_in_x_regs_instr::type_id::create(); + `DV_CHECK_FATAL($cast(zfinx_instr, instr), "Cast to zfinx instruction type failed!"); + randomize_zfinx_gpr(zfinx_instr, cv32e40p_zfinx_regs); + instr_list.push_back(zfinx_instr); + end + end else begin $cast(cv32_instr,instr); randomize_cv32e40p_gpr(cv32_instr, cv32e40p_avail_regs); randomize_cv32e40p_instr_imm(cv32_instr); @@ -1377,3 +1468,195 @@ class cv32e40p_xpulp_hwloop_isa_stress_stream extends cv32e40p_xpulp_hwloop_base endfunction endclass : cv32e40p_xpulp_hwloop_isa_stress_stream + +//Class: cv32e40p_xpulp_hwloop_exception +//Hwloop stream with exceptions +class cv32e40p_xpulp_hwloop_exception extends cv32e40p_xpulp_hwloop_base_stream; + + `uvm_object_utils_begin(cv32e40p_xpulp_hwloop_exception) + `uvm_field_int(num_of_xpulp_instr, UVM_DEFAULT) + `uvm_field_int(num_of_riscv_instr, UVM_DEFAULT) + `uvm_field_int(num_of_avail_regs, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_reg_t,cv32e40p_avail_regs, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_reg_t,cv32e40p_exclude_regs, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_instr_name_t,xpulp_exclude_instr, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_instr_name_t,riscv_exclude_common_instr, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_instr_name_t,riscv_exclude_instr, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_instr_group_t,riscv_exclude_group, UVM_DEFAULT) + `uvm_field_int(num_loops_active, UVM_DEFAULT) + `uvm_field_int(gen_nested_loop, UVM_DEFAULT) + `uvm_field_sarray_int(use_setup_inst, UVM_DEFAULT) + `uvm_field_sarray_int(use_loop_counti_inst, UVM_DEFAULT) + `uvm_field_sarray_int(use_loop_starti_inst, UVM_DEFAULT) + `uvm_field_sarray_int(use_loop_endi_inst, UVM_DEFAULT) + `uvm_field_sarray_int(use_loop_setupi_inst, UVM_DEFAULT) + `uvm_field_sarray_int(hwloop_count, UVM_DEFAULT) + `uvm_field_sarray_int(hwloop_counti, UVM_DEFAULT) + `uvm_field_sarray_int(num_hwloop_instr, UVM_DEFAULT) + `uvm_field_sarray_int(num_hwloop_ctrl_instr, UVM_DEFAULT) + `uvm_field_sarray_int(num_fill_instr_loop_ctrl_to_loop_start, UVM_DEFAULT) + `uvm_field_int(num_fill_instr_in_loop1_till_loop0_setup, UVM_DEFAULT) + `uvm_field_int(setup_l0_before_l1_start, UVM_DEFAULT) + `uvm_field_sarray_int(num_instr_cv_start_to_loop_start_label, UVM_DEFAULT) + `uvm_object_utils_end + + function new(string name = "cv32e40p_xpulp_hwloop_exception"); + super.new(name); + endfunction : new + + function void pre_randomize(); + super.pre_randomize(); + endfunction : pre_randomize + + function void post_randomize(); + cv32e40p_exclude_regs = {cv32e40p_exclude_regs, cfg.reserved_regs}; + //Exclude list for all random instruction generation part + riscv_exclude_common_instr = {CV_START, CV_STARTI, CV_END, CV_ENDI, CV_COUNT, CV_COUNTI, CV_SETUP, CV_SETUPI, + CV_ELW, + JAL, C_J, C_JAL}; + super.post_randomize(); + this.print(); + endfunction : post_randomize + + virtual function void insert_rand_instr_with_label(string label_str, + bit label_is_pulp_hwloop_body_label=0, + bit no_branch=1, + bit no_compressed=1, + bit no_fence=1); + riscv_instr instr; + cv32e40p_instr cv32_instr; + riscv_fp_in_x_regs_instr zfinx_instr; + string branch_imm_str; + riscv_instr_group_t riscv_exclude_xpulp[]; + + riscv_exclude_instr = {riscv_exclude_common_instr}; + + //use cfg for ebreak + if(cfg.no_ebreak) + riscv_exclude_instr = {riscv_exclude_instr, EBREAK, C_EBREAK}; + + if(no_compressed) + riscv_exclude_group = {riscv_exclude_group, RV32C, RV32FC}; + + riscv_exclude_xpulp = {riscv_exclude_group, RV32X}; + + //Create and Randomize array for avail_regs each time to ensure randomization + avail_regs = new[num_of_avail_regs]; + randomize_avail_regs(); + + instr = riscv_instr::type_id::create($sformatf("instr_%0s", label_str)); + + randcase + 2: instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), + .exclude_group(riscv_exclude_group)); + + 2: instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), + .exclude_group(riscv_exclude_xpulp)); + endcase + + if(instr.instr_name inside {BEQ, BNE, BLT, BGE, BLTU, BGEU, C_BEQZ, C_BNEZ, CV_BEQIMM, CV_BNEIMM}) begin + if(gen_nested_loop) + branch_imm_str = $sformatf("hwloop0_nested_end_stream%0d",stream_count); + else + branch_imm_str = end_label_s; + + instr.imm_str = branch_imm_str; + end + + //randomize immediates for each instruction + randomize_riscv_instr_imm(instr); + instr.has_label=1; + instr.label = label_str; + + //randomize GPRs for each instruction + if(instr.group != RV32ZFINX) begin + randomize_gpr(instr); + store_instr_gpr_handling(instr); + instr_list.push_back(instr); + end else begin + zfinx_instr = riscv_fp_in_x_regs_instr::type_id::create($sformatf("zfinx_instr_%0s", label_str)); + `DV_CHECK_FATAL($cast(zfinx_instr, instr), "Cast to zfinx instruction type failed!"); + randomize_zfinx_gpr(zfinx_instr, cv32e40p_zfinx_regs); + instr_list.push_back(zfinx_instr); + end + + + endfunction + + virtual function void insert_rand_instr(int unsigned num_rand_instr, + bit no_branch=1, + bit no_compressed=1, + bit no_fence=1); + + riscv_instr instr; + riscv_fp_in_x_regs_instr zfinx_instr; + int unsigned i; + string branch_imm_str; + riscv_instr_group_t riscv_exclude_xpulp[]; + + riscv_exclude_instr = {riscv_exclude_common_instr}; + + //use cfg for ebreak + if(cfg.no_ebreak) + riscv_exclude_instr = {riscv_exclude_instr, EBREAK, C_EBREAK}; + + if(no_compressed) + riscv_exclude_group = {riscv_exclude_group, RV32C, RV32FC}; + + `uvm_info("cv32e40p_xpulp_hwloop_base_stream", + $sformatf("insert_rand_instr- Number of Random instr to generate= %0d",num_rand_instr), + UVM_HIGH) + + if(num_rand_instr > MAX_HWLOOP_INSTR_GEN) begin + `uvm_fatal("cv32e40p_xpulp_hwloop_base_stream", + $sformatf("Too many hwloop instr. num_rand_instr = %0d",num_rand_instr)) + end + + riscv_exclude_xpulp = {riscv_exclude_group, RV32X}; + + i = 0; + while (i < num_rand_instr) begin + //Create and Randomize array for avail_regs each time to ensure randomization + avail_regs = new[num_of_avail_regs - reserved_rd.size()]; + randomize_avail_regs(); + + instr = riscv_instr::type_id::create($sformatf("instr_%0d", i)); + + randcase + 2: instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), + .exclude_group(riscv_exclude_group)); + + 2: instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), + .exclude_group(riscv_exclude_xpulp)); + endcase + + if(instr.instr_name inside {BEQ, BNE, BLT, BGE, BLTU, BGEU, C_BEQZ, C_BNEZ, CV_BEQIMM, CV_BNEIMM}) begin + if(gen_nested_loop) + branch_imm_str = $sformatf("hwloop0_nested_end_stream%0d",stream_count); + else + branch_imm_str = end_label_s; + + instr.imm_str = branch_imm_str; + end + + //randomize immediates for each instruction + randomize_riscv_instr_imm(instr); + + //randomize GPRs for each instruction + if(instr.group != RV32ZFINX) begin + randomize_gpr(instr); + store_instr_gpr_handling(instr); + instr_list.push_back(instr); + end else begin + zfinx_instr = riscv_fp_in_x_regs_instr::type_id::create($sformatf("zfinx_instr_%0d", i)); + `DV_CHECK_FATAL($cast(zfinx_instr, instr), "Cast to zfinx instruction type failed!"); + randomize_zfinx_gpr(zfinx_instr, cv32e40p_zfinx_regs); + instr_list.push_back(zfinx_instr); + end + + i++; + end + + endfunction +endclass : cv32e40p_xpulp_hwloop_exception + diff --git a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_pulp_instr_lib.sv b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_pulp_instr_lib.sv index cafac75e50..d5672c9d3b 100644 --- a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_pulp_instr_lib.sv +++ b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_pulp_instr_lib.sv @@ -97,24 +97,24 @@ class cv32e40p_xpulp_rand_stream extends cv32e40p_base_instr_stream; rand riscv_reg_t cv32e40p_avail_regs[]; rand riscv_reg_t cv32e40p_exclude_regs[]; - int unsigned num_of_reserved_regs; - riscv_reg_t cv32e40p_reserved_regs[]; - riscv_instr_name_t xpulp_exclude_instr[]; riscv_instr_category_t xpulp_include_category[]; + riscv_instr_name_t riscv_exclude_common_instr[]; riscv_instr_name_t riscv_exclude_instr[]; riscv_instr_group_t riscv_exclude_group[]; - riscv_instr riscv_instr_list[]; + + int unsigned num_zfinx_gpr; + int unsigned num_str_reserved_gpr; + riscv_reg_t cv32e40p_zfinx_regs[]; `uvm_object_utils_begin(cv32e40p_xpulp_rand_stream) `uvm_field_int(num_of_xpulp_instr, UVM_DEFAULT) `uvm_field_int(num_of_riscv_instr, UVM_DEFAULT) `uvm_field_int(num_of_avail_regs, UVM_DEFAULT) - `uvm_field_int(num_of_reserved_regs, UVM_DEFAULT) `uvm_field_sarray_enum(riscv_reg_t,cv32e40p_avail_regs, UVM_DEFAULT) `uvm_field_sarray_enum(riscv_reg_t,cv32e40p_exclude_regs, UVM_DEFAULT) - `uvm_field_sarray_enum(riscv_reg_t,cv32e40p_reserved_regs, UVM_DEFAULT) `uvm_field_sarray_enum(riscv_instr_name_t,xpulp_exclude_instr, UVM_DEFAULT) + `uvm_field_sarray_enum(riscv_instr_name_t,riscv_exclude_common_instr, UVM_DEFAULT) `uvm_field_sarray_enum(riscv_instr_name_t,riscv_exclude_instr, UVM_DEFAULT) `uvm_field_sarray_enum(riscv_instr_group_t,riscv_exclude_group, UVM_DEFAULT) `uvm_object_utils_end @@ -128,55 +128,66 @@ class cv32e40p_xpulp_rand_stream extends cv32e40p_base_instr_stream; } constraint avail_regs_pulp_instr_c { - num_of_avail_regs inside {[8:25]}; + if ((cfg.enable_fp_in_x_regs == 1) && (RV32ZFINX inside {riscv_instr_pkg::supported_isa})) { + num_of_avail_regs >= 8; + num_of_avail_regs <= (24 - num_zfinx_gpr - num_str_reserved_gpr); + } else { + num_of_avail_regs >= 8; + num_of_avail_regs <= (24 - num_str_reserved_gpr); + } } constraint cv32e40p_avail_regs_c { solve num_of_avail_regs before cv32e40p_exclude_regs; cv32e40p_avail_regs.size() == num_of_avail_regs; - cv32e40p_exclude_regs.size() == (32-num_of_reserved_regs-num_of_avail_regs); + cv32e40p_exclude_regs.size() == (32 - num_of_avail_regs - cfg.reserved_regs.size()); unique {cv32e40p_exclude_regs}; foreach(cv32e40p_exclude_regs[i]) { - !(cv32e40p_exclude_regs[i] inside {cv32e40p_reserved_regs}); + !(cv32e40p_exclude_regs[i] inside {cfg.reserved_regs}); } } function new(string name = "cv32e40p_xpulp_rand_stream"); super.new(name); - num_of_reserved_regs = 5; - cv32e40p_reserved_regs = new[num_of_reserved_regs]; - cv32e40p_reserved_regs = {ZERO, RA, SP, GP, TP}; - endfunction : new function void pre_randomize(); super.pre_randomize(); + uvm_default_printer.knobs.begin_elements = -1; //Exclude list for XPULP instruction generation part - xpulp_exclude_instr = { CV_BEQIMM, CV_BNEIMM, - CV_START, CV_STARTI, CV_END, CV_ENDI, CV_COUNT, CV_COUNTI, CV_SETUP, CV_SETUPI, + xpulp_exclude_instr = { CV_START, CV_STARTI, CV_END, CV_ENDI, CV_COUNT, CV_COUNTI, CV_SETUP, CV_SETUPI, CV_ELW, C_ADDI16SP }; //Exclude list for all random instruction generation part - riscv_exclude_instr = { CV_BEQIMM, CV_BNEIMM, - CV_START, CV_STARTI, CV_END, CV_ENDI, CV_COUNT, CV_COUNTI, CV_SETUP, CV_SETUPI, - CV_ELW, - C_ADDI16SP, - WFI, - URET, SRET, MRET, DRET, - ECALL, - JALR, JAL, C_JR, C_JALR, C_J, C_JAL}; + riscv_exclude_common_instr = { CV_START, CV_STARTI, CV_END, CV_ENDI, CV_COUNT, CV_COUNTI, CV_SETUP, CV_SETUPI, + CV_ELW, + C_ADDI16SP, + WFI, + URET, SRET, MRET, DRET, + ECALL, + JALR, JAL, C_JR, C_JALR, C_J, C_JAL }; + + num_zfinx_gpr = cv32e40p_cfg.num_zfinx_reserved_reg; + cv32e40p_zfinx_regs = new[num_zfinx_gpr]; + cv32e40p_zfinx_regs = cv32e40p_cfg.zfinx_reserved_gpr; + num_str_reserved_gpr = (!cv32e40p_cfg.no_load_store) ? 2 : 0; // TODO: add more randomization endfunction : pre_randomize function void post_randomize(); - cv32e40p_exclude_regs = {cv32e40p_exclude_regs,cv32e40p_reserved_regs}; + cv32e40p_exclude_regs = {cv32e40p_exclude_regs,cfg.reserved_regs}; + cv32e40p_exclude_regs.sort(); + + if((cv32e40p_exclude_regs.size() < 2) || (cv32e40p_exclude_regs.size() > 25)) + `uvm_fatal(this.get_type_name(), "cv32e40p_exclude_regs out of range") + this.print(); insert_rand_xpulp_instr(.no_branch(cfg.no_branch_jump), .no_compressed(cfg.disable_compressed_instr), .no_fence(cfg.no_fence), - .no_floating_point_instr(!cfg.enable_floating_point)); + .no_floating_point_instr(~(cfg.enable_floating_point | cfg.enable_fp_in_x_regs))); //super.post_randomize(); endfunction : post_randomize @@ -186,20 +197,25 @@ class cv32e40p_xpulp_rand_stream extends cv32e40p_base_instr_stream; bit no_fence=1, bit no_floating_point_instr=0); - riscv_instr instr; - cv32e40p_instr cv32_instr; - string str; - int i; + riscv_instr instr; + cv32e40p_instr cv32_instr; + riscv_fp_in_x_regs_instr zfinx_instr; + string str; + int i; + riscv_instr_group_t riscv_exclude_xpulp[]; + int rv32_ins, pulp_ins; + + riscv_exclude_instr = {riscv_exclude_common_instr}; //use cfg for ebreak if(cfg.no_ebreak) riscv_exclude_instr = {riscv_exclude_instr, EBREAK, C_EBREAK}; if(no_branch) - riscv_exclude_instr = {riscv_exclude_instr, BEQ, BNE, BLT, BGE, BLTU, BGEU, C_BEQZ, C_BNEZ}; + riscv_exclude_instr = {riscv_exclude_instr, BEQ, BNE, BLT, BGE, BLTU, BGEU, C_BEQZ, C_BNEZ, CV_BEQIMM, CV_BNEIMM}; if(no_compressed) - riscv_exclude_group = {riscv_exclude_group, RV32C}; + riscv_exclude_group = {riscv_exclude_group, RV32C, RV32FC}; if(no_fence) riscv_exclude_instr = {riscv_exclude_instr, FENCE, FENCE_I}; @@ -208,61 +224,71 @@ class cv32e40p_xpulp_rand_stream extends cv32e40p_base_instr_stream; riscv_exclude_group = {riscv_exclude_group, RV32F, RV32ZFINX}; `uvm_info("cv32e40p_xpulp_rand_stream", - $sformatf("Number of XPULP instr to be generated = %0d",num_of_xpulp_instr),UVM_HIGH) + $sformatf("Total XPULP+RISCV instr gen in test %0d + %0d",num_of_xpulp_instr,num_of_riscv_instr),UVM_HIGH) - //(1) Generate random xpulp instructions - i = 0; - while (i < num_of_xpulp_instr) begin - //Create and Randomize array for avail_regs each time to ensure randomization - //To resolve the randomization issue within the same stream need this step - cv32e40p_avail_regs = new[num_of_avail_regs]; - std::randomize(cv32e40p_avail_regs) with { foreach(cv32e40p_avail_regs[i]) { - !(cv32e40p_avail_regs[i] inside {cv32e40p_exclude_regs}); - } - }; - - cv32_instr = cv32e40p_instr::type_id::create($sformatf("cv32_instr_%0d", i)); - cv32_instr = cv32e40p_instr::get_xpulp_instr(.exclude_instr(xpulp_exclude_instr), - .include_category(xpulp_include_category)); - - //randomize GPRs for each instruction - randomize_cv32e40p_gpr(cv32_instr, cv32e40p_avail_regs); - - //randomize immediates for each instruction - randomize_cv32e40p_instr_imm(cv32_instr); - - instr_list.push_back(cv32_instr); - i++; + //Exclude RV32X instr for riscv_exclude_xpulp + riscv_exclude_xpulp = {riscv_exclude_group, RV32X}; + rv32_ins = num_of_riscv_instr; + pulp_ins = num_of_xpulp_instr; - end // while num_of_xpulp_instr - - //(2) Generate all random instructions - riscv_instr_list = new[num_of_riscv_instr]; - for (i = 0; i < num_of_riscv_instr; i++) begin - - //Create and Randomize array for avail_regs each time to ensure randomization - avail_regs = new[num_of_avail_regs]; - randomize_avail_regs(); - - //Dont include RV32X instr here again - riscv_exclude_group = {riscv_exclude_group, RV32X}; - - riscv_instr_list[i] = riscv_instr::type_id::create($sformatf("riscv_instr_list_%0d", i)); - - //exclude pulp instructions here - riscv_instr_list[i] = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), - .exclude_group(riscv_exclude_group)); - - //randomize GPRs for each instruction - randomize_gpr(riscv_instr_list[i]); - - //randomize immediates for each instruction - randomize_riscv_instr_imm(riscv_instr_list[i]); + i = 0; + while (i < (num_of_xpulp_instr+num_of_riscv_instr)) begin + + randcase + pulp_ins: + begin + //Create and Randomize array for avail_regs each time to ensure randomization + //To resolve the randomization issue within the same stream need this step + cv32e40p_avail_regs = new[num_of_avail_regs]; + std::randomize(cv32e40p_avail_regs) with { foreach(cv32e40p_avail_regs[i]) { + !(cv32e40p_avail_regs[i] inside {cv32e40p_exclude_regs}); + } + }; + cv32_instr = cv32e40p_instr::type_id::create($sformatf("cv32_instr_%0d", i)); + cv32_instr = cv32e40p_instr::get_xpulp_instr(.exclude_instr(xpulp_exclude_instr), + .include_category(xpulp_include_category)); + + //randomize GPRs for each instruction + randomize_cv32e40p_gpr(cv32_instr, cv32e40p_avail_regs); + + //randomize immediates for each instruction + randomize_cv32e40p_instr_imm(cv32_instr); + + instr_list.push_back(cv32_instr); + end + rv32_ins: + begin + //Create and Randomize array for avail_regs each time to ensure randomization + avail_regs = new[num_of_avail_regs]; + randomize_avail_regs(); + + instr = riscv_instr::type_id::create($sformatf("riscv_instr_%0d", i)); + + //exclude pulp instructions here + instr = riscv_instr::get_rand_instr(.exclude_instr(riscv_exclude_instr), + .exclude_group(riscv_exclude_xpulp)); + + //randomize immediates for each instruction + randomize_riscv_instr_imm(instr); + + //randomize GPRs for each instruction + if(instr.group != RV32ZFINX) begin + randomize_gpr(instr); + store_instr_gpr_handling(instr); + instr_list.push_back(instr); + end else begin + zfinx_instr = riscv_fp_in_x_regs_instr::type_id::create($sformatf("zfinx_instr_%0d", i)); + `DV_CHECK_FATAL($cast(zfinx_instr, instr), "Cast to zfinx instruction type failed!"); + randomize_zfinx_gpr(zfinx_instr, cv32e40p_zfinx_regs); + instr_list.push_back(zfinx_instr); + end + + end + endcase - end // num_of_riscv_instr + i++; - //mix steams for randomization - mix_instr_stream(riscv_instr_list); + end // while endfunction diff --git a/cv32e40p/env/corev-dv/target/cv32e40p/cv32e40p_supported_isa.svh b/cv32e40p/env/corev-dv/target/cv32e40p/cv32e40p_supported_isa.svh index e1c9907345..960d289b25 100644 --- a/cv32e40p/env/corev-dv/target/cv32e40p/cv32e40p_supported_isa.svh +++ b/cv32e40p/env/corev-dv/target/cv32e40p/cv32e40p_supported_isa.svh @@ -9,7 +9,7 @@ `define RV_DV_ISA { RV32I, RV32M, RV32C, RV32X } `else //FPU = 1 `ifndef ZFINX - `define RV_DV_ISA { RV32I, RV32M, RV32C, RV32X, RV32F } + `define RV_DV_ISA { RV32I, RV32M, RV32C, RV32X, RV32F, RV32FC } `else `define FP_IN_X_REGS `define RV_DV_ISA { RV32I, RV32M, RV32C, RV32X, RV32ZFINX } @@ -18,7 +18,7 @@ `else //PULP = 0, FPU = 1 `ifdef FPU `ifndef ZFINX - `define RV_DV_ISA { RV32I, RV32M, RV32C, RV32F } + `define RV_DV_ISA { RV32I, RV32M, RV32C, RV32F, RV32FC } `else `define FP_IN_X_REGS `define RV_DV_ISA { RV32I, RV32M, RV32C, RV32ZFINX } @@ -28,7 +28,7 @@ //Following defines are provided to allow overwrite from test yaml files `ifdef RV_DV_ISA_RV32IMFC -`define RV_DV_ISA { RV32I, RV32M, RV32C, RV32F } +`define RV_DV_ISA { RV32I, RV32M, RV32C, RV32F, RV32FC } `endif `ifdef RV_DV_ISA_RV32IMC_ZFINX @@ -41,7 +41,7 @@ `endif `ifdef RV_DV_ISA_RV32IMFC_X -`define RV_DV_ISA { RV32I, RV32M, RV32C, RV32F, RV32X } +`define RV_DV_ISA { RV32I, RV32M, RV32C, RV32F, RV32FC, RV32X } `endif `ifdef RV_DV_ISA_RV32IMC_ZFINX_X diff --git a/cv32e40p/regress/cv32e40p_xpulp_rand_tests.yaml b/cv32e40p/regress/cv32e40p_xpulp_rand_tests.yaml index 474ef5caaf..e3a7edf50e 100644 --- a/cv32e40p/regress/cv32e40p_xpulp_rand_tests.yaml +++ b/cv32e40p/regress/cv32e40p_xpulp_rand_tests.yaml @@ -22,54 +22,41 @@ builds: cmd: make comp comp_corev-dv cfg: pulp dir: cv32e40p/sim/uvmt - iss: 1 - cov: 1 uvmt_cv32e40p_pulp_fpu: cmd: make comp comp_corev-dv cfg: pulp_fpu dir: cv32e40p/sim/uvmt - iss: 1 - cov: 1 uvmt_cv32e40p_pulp_fpu_1cyclat: cmd: make comp comp_corev-dv cfg: pulp_fpu_1cyclat dir: cv32e40p/sim/uvmt - iss: 1 - cov: 1 uvmt_cv32e40p_pulp_fpu_2cyclat: cmd: make comp comp_corev-dv cfg: pulp_fpu_2cyclat dir: cv32e40p/sim/uvmt - iss: 1 - cov: 1 uvmt_cv32e40p_pulp_fpu_zfinx: cmd: make comp comp_corev-dv cfg: pulp_fpu_zfinx dir: cv32e40p/sim/uvmt - iss: 1 - cov: 1 uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat: cmd: make comp comp_corev-dv cfg: pulp_fpu_zfinx_1cyclat dir: cv32e40p/sim/uvmt - iss: 1 - cov: 1 uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat: cmd: make comp comp_corev-dv cfg: pulp_fpu_zfinx_2cyclat dir: cv32e40p/sim/uvmt - iss: 1 - cov: 1 # List of tests tests: corev_rand_pulp_instr_test: + testname: corev_rand_pulp_instr_test description: pulp random test builds: - uvmt_cv32e40p_pulp @@ -80,12 +67,11 @@ tests: - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat dir: cv32e40p/sim/uvmt - cmd: make gen_corev-dv test TEST=corev_rand_pulp_instr_test + cmd: make gen_corev-dv test TEST=corev_rand_pulp_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=10000000" num: 10 - iss: 1 - cov: 1 corev_rand_pulp_hwloop_test: + testname: corev_rand_pulp_hwloop_test description: hwloop random test builds: - uvmt_cv32e40p_pulp @@ -96,12 +82,11 @@ tests: - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat dir: cv32e40p/sim/uvmt - cmd: make gen_corev-dv test TEST=corev_rand_pulp_hwloop_test + cmd: make gen_corev-dv test TEST=corev_rand_pulp_hwloop_test CFG_PLUSARGS="+UVM_TIMEOUT=10000000" num: 10 - iss: 1 - cov: 1 corev_rand_pulp_mac_instr_test: + testname: corev_rand_pulp_mac_instr_test description: pulp mac instr random test builds: - uvmt_cv32e40p_pulp @@ -112,12 +97,11 @@ tests: - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat dir: cv32e40p/sim/uvmt - cmd: make gen_corev-dv test TEST=corev_rand_pulp_mac_instr_test + cmd: make gen_corev-dv test TEST=corev_rand_pulp_mac_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=10000000" num: 5 - iss: 1 - cov: 1 corev_rand_pulp_simd_instr_test: + testname: corev_rand_pulp_simd_instr_test description: pulp simd instr random test builds: - uvmt_cv32e40p_pulp @@ -128,12 +112,75 @@ tests: - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat dir: cv32e40p/sim/uvmt - cmd: make gen_corev-dv test TEST=corev_rand_pulp_simd_instr_test + cmd: make gen_corev-dv test TEST=corev_rand_pulp_simd_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=10000000" num: 5 - iss: 1 - cov: 1 + + corev_rand_pulp_instr_ebreak_debug_test: + testname: corev_rand_pulp_instr_test + description: pulp rand test with ebreak debug + builds: + - uvmt_cv32e40p_pulp + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_pulp_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=10000000" + test_cfg: debug_ebreak + num: 1 + + corev_rand_pulp_instr_single_step_debug_test: + testname: corev_rand_pulp_instr_test + description: pulp rand test with single-step debug + builds: + - uvmt_cv32e40p_pulp + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_pulp_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=10000000" + test_cfg: debug_single_step_en + num: 1 + + corev_rand_pulp_instr_interrupt_test: + testname: corev_rand_pulp_instr_test + description: pulp instr test with random interrupts + builds: + - uvmt_cv32e40p_pulp + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_pulp_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=10000000" + test_cfg: gen_rand_int + num: 2 + + corev_rand_pulp_illegal_instr_test: + testname: corev_rand_pulp_instr_test + description: pulp instr test with illegal instructions + builds: + - uvmt_cv32e40p_pulp + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_pulp_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=10000000" + test_cfg: insert_illegal_instr + num: 2 corev_rand_pulp_hwloop_debug: + testname: corev_rand_pulp_hwloop_debug description: hwloop debug random test builds: - uvmt_cv32e40p_pulp @@ -144,7 +191,101 @@ tests: - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat dir: cv32e40p/sim/uvmt - cmd: make gen_corev-dv test TEST=corev_rand_pulp_hwloop_debug + cmd: make gen_corev-dv test TEST=corev_rand_pulp_hwloop_debug CFG_PLUSARGS="+UVM_TIMEOUT=10000000" + num: 2 + + corev_rand_pulp_hwloop_debug_ebreak: + testname: corev_rand_pulp_hwloop_debug + description: hwloop ebreak debug random test + builds: + - uvmt_cv32e40p_pulp + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_pulp_hwloop_debug CFG_PLUSARGS="+UVM_TIMEOUT=10000000" + test_cfg: debug_ebreak + num: 2 + + corev_rand_pulp_hwloop_debug_single_step: + testname: corev_rand_pulp_hwloop_debug + description: hwloop single-step debug random test + builds: + - uvmt_cv32e40p_pulp + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_pulp_hwloop_debug CFG_PLUSARGS="+UVM_TIMEOUT=10000000" + test_cfg: debug_single_step_en + num: 2 + + corev_rand_pulp_hwloop_interrupt_test: + testname: corev_rand_pulp_hwloop_test + description: hwloop test with random interrupts + builds: + - uvmt_cv32e40p_pulp + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_pulp_hwloop_test CFG_PLUSARGS="+UVM_TIMEOUT=10000000" + test_cfg: gen_rand_int num: 5 - iss: 1 - cov: 1 + + corev_rand_pulp_hwloop_illegal_instr_test: + testname: corev_rand_pulp_hwloop_test + description: hwloop test with illegal instructions + builds: + - uvmt_cv32e40p_pulp + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_pulp_hwloop_test CFG_PLUSARGS="+UVM_TIMEOUT=10000000" + test_cfg: insert_illegal_instr + num: 2 + + corev_rand_pulp_hwloop_exception: + testname: corev_rand_pulp_hwloop_exception + description: hwloop exception test + builds: + - uvmt_cv32e40p_pulp + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_pulp_hwloop_exception CFG_PLUSARGS="+UVM_TIMEOUT=10000000" + num: 2 + + corev_rand_pulp_hwloop_exception_single_step_debug: + testname: corev_rand_pulp_hwloop_exception + description: hwloop exception test with single step debug + builds: + - uvmt_cv32e40p_pulp + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_pulp_hwloop_exception CFG_PLUSARGS="+UVM_TIMEOUT=10000000" + test_cfg: debug_single_step_en + num: 1 + diff --git a/cv32e40p/regress/cv32e40pv2_benchmarks.yaml b/cv32e40p/regress/cv32e40pv2_benchmarks.yaml new file mode 100644 index 0000000000..2017d6c0cb --- /dev/null +++ b/cv32e40p/regress/cv32e40pv2_benchmarks.yaml @@ -0,0 +1,36 @@ +# Copyright 2023 Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# Header +name: cv32e40pv2_benchmarks +description: run available benchmarks + +# List of builds +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: + coremark: + build: uvmt_cv32e40p + dir: cv32e40p/sim/uvmt + cmd: make test TEST=coremark + + dhrystone: + build: uvmt_cv32e40p + dir: cv32e40p/sim/uvmt + cmd: make test TEST=dhrystone + + fibonacci: + build: uvmt_cv32e40p + dir: cv32e40p/sim/uvmt + cmd: make test TEST=fibonacci diff --git a/cv32e40p/regress/cv32e40pv2_ci_check.yaml b/cv32e40p/regress/cv32e40pv2_ci_check.yaml index 7f6f8d5529..6aec162695 100644 --- a/cv32e40p/regress/cv32e40pv2_ci_check.yaml +++ b/cv32e40p/regress/cv32e40pv2_ci_check.yaml @@ -3,16 +3,6 @@ name: cv32e40pv2_ci_check description: Commit sanity for the cv32e40pv2 builds: - clean_fw: - cmd: make clean-bsp clean_test_programs - dir: cv32e40p/sim/uvmt - - # Cleaning previous clone of corev-dv - clean_corev-dv: - cmd: make clean_riscv-dv clone_riscv-dv - dir: cv32e40p/sim/uvmt - - # One tb per configuration uvmt_cv32e40p_default: cmd: make comp comp_corev-dv cfg: default @@ -93,7 +83,6 @@ builds: cfg: pulp_cluster_fpu_zfinx_2cyclat dir: cv32e40p/sim/uvmt -# make sure that everything is compiling and running, with iss tests: hello-world: builds: @@ -115,36 +104,29 @@ tests: - uvmt_cv32e40p_pulp_cluster_fpu_zfinx_2cyclat description: UVM Hello World Test dir: cv32e40p/sim/uvmt - iss: 1 - cov: 0 cmd: make test COREV=YES TEST=hello-world + num: 1 interrupt_test: build: uvmt_cv32e40p_pulp_fpu description: Interrupt directed on PULP+FPU HW dir: cv32e40p/sim/uvmt - iss: 1 - cov: 0 cmd: make test COREV=YES TEST=interrupt_test + num: 1 debug_test: build: uvmt_cv32e40p_pulp_fpu dir: cv32e40p/sim/uvmt - iss: 1 - cov: 0 cmd: make test COREV=YES TEST=debug_test + num: 1 - corev_rand_fp_instr_sanity_test_nonzfinx: - testname: corev_rand_fp_instr_sanity_test + corev_rand_fp_instr_sanity_test: builds: - uvmt_cv32e40p_pulp_fpu - uvmt_cv32e40p_pulp_fpu_1cyclat - uvmt_cv32e40p_pulp_fpu_2cyclat test_cfg: floating_pt_instr_en dir: cv32e40p/sim/uvmt - iss: 1 - cov: 0 - # cmd: make gen_corev-dv test COREV=YES TEST=corev_sanity_fp_instr_test cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_sanity_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" corev_rand_fp_instr_sanity_test_zfinx: @@ -153,16 +135,16 @@ tests: - uvmt_cv32e40p_pulp_fpu_zfinx - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat - test_cfg: floating_pt_zfinx_instr_en dir: cv32e40p/sim/uvmt - iss: 1 - cov: 0 - # cmd: make gen_corev-dv test COREV=YES TEST=corev_sanity_fp_zfinx_instr_test - cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_sanity_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" + cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_sanity_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" + test_cfg: floating_pt_zfinx_instr_en corev_rand_pulp_instr_test: build: uvmt_cv32e40p_pulp dir: cv32e40p/sim/uvmt - iss: 1 - cov: 0 cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_instr_test + + corev_rand_pulp_hwloop_test: + build: uvmt_cv32e40p_pulp + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_hwloop_test diff --git a/cv32e40p/regress/cv32e40pv2_fpu.yaml b/cv32e40p/regress/cv32e40pv2_fpu.yaml index 768664f79c..2dfbe4520e 100644 --- a/cv32e40p/regress/cv32e40pv2_fpu.yaml +++ b/cv32e40p/regress/cv32e40pv2_fpu.yaml @@ -17,19 +17,16 @@ builds: cfg: pulp_fpu dir: cv32e40p/sim/uvmt iss: 0 - cov: 0 uvmt_cv32e40p_pulp_fpu_1cyclat: cmd: make comp comp_corev-dv cfg: pulp_fpu_1cyclat dir: cv32e40p/sim/uvmt iss: 0 - cov: 0 uvmt_cv32e40p_pulp_fpu_2cyclat: cmd: make comp comp_corev-dv cfg: pulp_fpu_2cyclat dir: cv32e40p/sim/uvmt iss: 0 - cov: 0 # zfinx related tests uvmt_cv32e40p_pulp_fpu_zfinx: @@ -37,19 +34,16 @@ builds: cfg: pulp_fpu_zfinx dir: cv32e40p/sim/uvmt iss: 0 - cov: 0 uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat: cmd: make comp comp_corev-dv cfg: pulp_fpu_zfinx_1cyclat dir: cv32e40p/sim/uvmt iss: 0 - cov: 0 uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat: cmd: make comp comp_corev-dv cfg: pulp_fpu_zfinx_2cyclat dir: cv32e40p/sim/uvmt iss: 0 - cov: 0 # run many tests: @@ -64,7 +58,6 @@ tests: test_cfg: floating_pt_instr_en dir: cv32e40p/sim/uvmt cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_sanity_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" - num: 1 corev_rand_fp_instr_test_nonzfinx: testname: corev_rand_fp_instr_test @@ -76,7 +69,6 @@ tests: test_cfg: floating_pt_instr_en dir: cv32e40p/sim/uvmt cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" - num: 1 corev_rand_fp_instr_mlt_cyc_test_nonzfinx: testname: corev_rand_fp_instr_mlt_cyc_test @@ -88,7 +80,6 @@ tests: test_cfg: floating_pt_instr_en dir: cv32e40p/sim/uvmt cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_mlt_cyc_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" - num: 1 corev_rand_fp_instr_w_special_ops_test_nonzfinx: testname: corev_rand_fp_instr_w_special_ops_test @@ -100,7 +91,6 @@ tests: test_cfg: floating_pt_instr_en dir: cv32e40p/sim/uvmt cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_w_special_ops_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" - num: 1 corev_rand_fp_instr_data_fwd_test_nonzfinx: testname: corev_rand_fp_instr_data_fwd_test @@ -112,7 +102,6 @@ tests: test_cfg: floating_pt_instr_en dir: cv32e40p/sim/uvmt cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_data_fwd_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" - num: 1 # zfinx related tests corev_rand_fp_instr_sanity_test_zfinx: @@ -125,7 +114,6 @@ tests: test_cfg: floating_pt_zfinx_instr_en dir: cv32e40p/sim/uvmt cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_sanity_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" - num: 1 corev_rand_fp_instr_test_zfinx: testname: corev_rand_fp_instr_test @@ -137,7 +125,6 @@ tests: test_cfg: floating_pt_zfinx_instr_en dir: cv32e40p/sim/uvmt cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" - num: 1 corev_rand_fp_instr_mlt_cyc_test_zfinx: testname: corev_rand_fp_instr_mlt_cyc_test @@ -149,7 +136,6 @@ tests: test_cfg: floating_pt_zfinx_instr_en dir: cv32e40p/sim/uvmt cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_mlt_cyc_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" - num: 1 corev_rand_fp_instr_w_special_ops_test_zfinx: testname: corev_rand_fp_instr_w_special_ops_test @@ -161,7 +147,6 @@ tests: test_cfg: floating_pt_zfinx_instr_en dir: cv32e40p/sim/uvmt cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_w_special_ops_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" - num: 1 corev_rand_fp_instr_data_fwd_test_zfinx: testname: corev_rand_fp_instr_data_fwd_test @@ -173,7 +158,6 @@ tests: test_cfg: floating_pt_zfinx_instr_en dir: cv32e40p/sim/uvmt cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_data_fwd_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" - num: 1 # Info: @@ -182,7 +166,4 @@ tests: # 3) use below commands to generate regression file. e.g below for vrun rmdb file # - default (follow yaml settings): %./cv_regress --rmdb --file=.yaml --outfile=.rmdb --simulator=vsim # - override : %./cv_regress --rmdb --file=.yaml --outfile=.rmdb --simulator=vsim --iss=1 --cov --num=2 -# 4) important switches that should be considered during overriding: --cov, --iss and --num -# -# potantial issues? -# 1) the merged ucdb - how it is hanndle in this case +# 4) important switches commonly use together with cmd to run with this yaml file: --cov, --iss=<1/0> and --num= diff --git a/cv32e40p/regress/cv32e40pv2_fpu_instr.yaml b/cv32e40p/regress/cv32e40pv2_fpu_instr.yaml new file mode 100644 index 0000000000..5dadadcc9f --- /dev/null +++ b/cv32e40p/regress/cv32e40pv2_fpu_instr.yaml @@ -0,0 +1,57 @@ +# Copyright 2023 Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# Header +name: cv32e40pv2_fpu_instr +description: regression for CV32E40Pv2, focused on FP instructions + +# List of builds +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_fpu + +# List of tests +tests: + corev_rand_fp_instr_data_fwd_test: + build: uvmt_cv32e40p + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_data_fwd_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" + test_cfg: floating_pt_instr_en + + corev_rand_fp_instr_mlt_cyc_test: + build: uvmt_cv32e40p + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_mlt_cyc_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" + test_cfg: floating_pt_instr_en + + corev_rand_fp_instr_sanity_test: + build: uvmt_cv32e40p + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_sanity_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" + test_cfg: floating_pt_instr_en + + corev_rand_fp_instr_test: + build: uvmt_cv32e40p + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" + test_cfg: floating_pt_instr_en + + corev_rand_fp_instr_w_special_ops_test: + build: uvmt_cv32e40p + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test TEST=corev_rand_fp_instr_w_special_ops_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" + test_cfg: floating_pt_instr_en + + fpu_bugs_test: + build: uvmt_cv32e40p + dir: cv32e40p/sim/uvmt + cmd: make test TEST=fpu_bugs_test + num: 1 diff --git a/cv32e40p/regress/cv32e40pv2_full_unique_bld1.yaml b/cv32e40p/regress/cv32e40pv2_full_unique_bld1.yaml new file mode 100644 index 0000000000..ece92c5ff3 --- /dev/null +++ b/cv32e40p/regress/cv32e40pv2_full_unique_bld1.yaml @@ -0,0 +1,435 @@ +# Copyright 2023 Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# YAML file to specify a regression testlist +# Note that the COREV=YES is set for all tests in this regression. +# This means you need to have a toolchain at COREV_SW_TOOLCHAIN (see Common.mk) +--- +# Header +name: cv32_full_build +description: Regression list for most of the tests in CV32E40P with specific build(s) + +# List of builds +builds: + # note: + # 1) do not include clean_fw and clean_core-dv because regression should be able to run parallel with different builds + # 2) every yaml should have unique build so that the parallel regressions from diff yaml file have no conflicts + # 3) cov is disabled by default and should be explicitely enabled with command switch --cov + # 4) fixme: iss is disabled by default and should be explcitely enabled with command switch --iss=yes (maybe enable by default is better, to be decided later) + # 5) num is default as minimum and should be explicitely enabled with command switch --num= + + # 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 + # cov: 0 + uvmt_cv32e40p_pulp: + cmd: make comp comp_corev-dv + dir: cv32e40p/sim/uvmt + cfg: pulp + +# ==================================================================================== +# LIST OF TESTS + +# ==================================================================================== +# V2 PULP tests +# ==================================================================================== +# ----------------------------------------------------------------------------------- +tests: + # ----------------------------------------------------------------------------------- + # corev_rand_pulp_instr_test + corev_rand_pulp_instr_test: + build: uvmt_cv32e40p_pulp + description: corev_rand_pulp_instr_test + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_instr_test + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_pulp_simd_test + corev_rand_pulp_simd_instr_test: + build: uvmt_cv32e40p_pulp + description: corev_rand_pulp_simd_instr_test + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_simd_instr_test + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_pulp_mac_test + corev_rand_pulp_mac_instr_test: + build: uvmt_cv32e40p_pulp + description: corev_rand_pulp_mac_instr_test + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_mac_instr_test + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_pulp_hwloop_test + corev_rand_pulp_hwloop_test: + build: uvmt_cv32e40p_pulp + description: corev_rand_pulp_hwloop_test + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_hwloop_test + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_debug_ebreak_xpulp + corev_rand_debug_ebreak_xpulp: + build: uvmt_cv32e40p_pulp + description: corev_rand_debug_ebreak_xpulp + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_debug_ebreak_xpulp + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_debug_single_step_xpulp + corev_rand_debug_single_step_xpulp: + build: uvmt_cv32e40p_pulp + description: corev_rand_debug_single_step_xpulp + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_debug_single_step_xpulp + iss: 1 + + + # ==================================================================================== + # V1 rand tests re-used with v2 features + # ==================================================================================== + # ----------------------------------------------------------------------------------- + # corev_rand_instr_long_stall + corev_rand_instr_long_stall: + build: uvmt_cv32e40p_pulp + description: corev_rand_instr_long_stall + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_instr_long_stall + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_interrupt + corev_rand_interrupt: + build: uvmt_cv32e40p_pulp + description: legacy v1 corev_rand_interrupt with added instructions + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_interrupt_debug + corev_rand_interrupt_debug: + build: uvmt_cv32e40p_pulp + description: corev_rand_interrupt_debug + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_debug + iss: 1 + + corev_rand_interrupt_exception: + builds: + - uvmt_cv32e40p_pulp + description: corev_rand_interrupt_exception + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_exception + iss: 1 + + corev_rand_interrupt_nested: + builds: + - uvmt_cv32e40p_pulp + description: corev_rand_interrupt_nested + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_nested + iss: 1 + + corev_rand_interrupt_wfi_mem_stress: + builds: + - uvmt_cv32e40p_pulp + description: corev_rand_interrupt_wfi_mem_stress + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_wfi_mem_stress + iss: 1 + + corev_rand_jump_stress_test: + builds: + - uvmt_cv32e40p_pulp + description: corev_rand_jump_stress_test + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_jump_stress_test + iss: 1 + + +# ==================================================================================== +# V1 test re-used +# ==================================================================================== +# ----------------------------------------------------------------------------------- + hello-world: + builds: + - uvmt_cv32e40p_pulp + description: uvm_hello_world_test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=hello-world + iss: 1 + + hpmcounter_basic_test: + builds: + - uvmt_cv32e40p_pulp + description: Hardware performance counter basic test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=hpmcounter_basic_test + iss: 1 + + hpmcounter_hazard_test: + builds: + - uvmt_cv32e40p_pulp + description: Hardware performance counter hazard test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=hpmcounter_hazard_test + iss: 1 + + riscv_ebreak_test_0: + builds: + - uvmt_cv32e40p_pulp + description: Static corev-dv ebreak + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=riscv_ebreak_test_0 + iss: 1 + + riscv_arithmetic_basic_test_0: + builds: + - uvmt_cv32e40p_pulp + description: Static riscv-dv arithmetic test 0 + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=riscv_arithmetic_basic_test_0 + iss: 1 + + riscv_arithmetic_basic_test_1: + builds: + - uvmt_cv32e40p_pulp + description: Static riscv-dv arithmetic test 1 + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=riscv_arithmetic_basic_test_1 + iss: 1 + + illegal: + builds: + - uvmt_cv32e40p_pulp + description: Illegal-riscv-tests + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=illegal + iss: 1 + + fibonacci: + builds: + - uvmt_cv32e40p_pulp + description: Fibonacci test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=fibonacci + iss: 1 + + misalign: + builds: + - uvmt_cv32e40p_pulp + description: Misalign test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=misalign + iss: 1 + + dhrystone: + builds: + - uvmt_cv32e40p_pulp + description: Dhrystone test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=dhrystone + iss: 1 + + debug_test: + builds: + - uvmt_cv32e40p_pulp + description: Debug Test 1 + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test + iss: 1 + + debug_test_reset: + builds: + - uvmt_cv32e40p_pulp + description: Debug reset test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_reset + iss: 1 + + debug_test_trigger: + builds: + - uvmt_cv32e40p_pulp + description: Debug trigger test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_trigger + iss: 1 + + debug_test_known_miscompares: + builds: + - uvmt_cv32e40p_pulp + description: Debug test which contains known miscompares + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_known_miscompares + iss: 0 + + debug_test_boot_set: + builds: + - uvmt_cv32e40p_pulp + description: Debug test target debug_req at BOOT_SET + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_boot_set + iss: 1 + + interrupt_bootstrap: + builds: + - uvmt_cv32e40p_pulp + description: Interrupt bootstrap test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=interrupt_bootstrap + iss: 1 + + interrupt_test: + builds: + - uvmt_cv32e40p_pulp + description: Interrupt test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=interrupt_test + iss: 1 + + +# ==================================================================================== +# V1 legacy pulp tests +# ==================================================================================== +# ----------------------------------------------------------------------------------- + pulp_bit_manipulation: + build: uvmt_cv32e40p_pulp + description: pulp_bit_manipulation legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_bit_manipulation + iss: 1 + + pulp_general_alu: + build: uvmt_cv32e40p_pulp + description: pulp_general_alu legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_general_alu + iss: 1 + + pulp_immediate_branching: + build: uvmt_cv32e40p_pulp + description: pulp_immediate_branching legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_immediate_branching + iss: 1 + + pulp_multiply_accumulate: + build: uvmt_cv32e40p_pulp + description: pulp_multiply_accumulate legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_multiply_accumulate + iss: 1 + + pulp_post_increment_load_store: + build: uvmt_cv32e40p_pulp + description: pulp_post_increment_load_store legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_post_increment_load_store + iss: 1 + + pulp_vectorial_add_sub: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_add_sub legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_add_sub + iss: 1 + + pulp_vectorial_avg: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_avg legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_avg + iss: 1 + + pulp_vectorial_bit_manip: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_bit_manip legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_bit_manip + iss: 1 + + pulp_vectorial_bitwise: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_bitwise legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_bitwise + iss: 1 + + pulp_vectorial_comparison_1: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_comparison_1 legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_comparison_1 + iss: 1 + + pulp_vectorial_comparison_2: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_comparison_2 legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_comparison_2 + iss: 1 + + pulp_vectorial_comparison_3: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_comparison_3 legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_comparison_3 + iss: 1 + + pulp_vectorial_complex: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_complex legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_complex + iss: 1 + + pulp_vectorial_dot_product_1: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_dot_product_1 legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_dot_product_1 + iss: 1 + + pulp_vectorial_dot_product_2: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_dot_product_2 legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_dot_product_2 + iss: 1 + + pulp_vectorial_max: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_max legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_max + iss: 1 + + pulp_vectorial_min: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_min legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_min + iss: 1 + + pulp_vectorial_shift: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_shift legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_shift + iss: 1 + + pulp_vectorial_shuffle_pack: + build: uvmt_cv32e40p_pulp + description: pulp_vectorial_shuffle_pack legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=pulp_vectorial_shuffle_pack + iss: 1 diff --git a/cv32e40p/regress/cv32e40pv2_full_unique_bld2.yaml b/cv32e40p/regress/cv32e40pv2_full_unique_bld2.yaml new file mode 100644 index 0000000000..81b799a59e --- /dev/null +++ b/cv32e40p/regress/cv32e40pv2_full_unique_bld2.yaml @@ -0,0 +1,344 @@ +# Copyright 2023 Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# YAML file to specify a regression testlist +# Note that the COREV=YES is set for all tests in this regression. +# This means you need to have a toolchain at COREV_SW_TOOLCHAIN (see Common.mk) +--- +# Header +name: cv32_full_build +description: Regression list for most of the tests in CV32E40P with specific build(s) + +# List of builds +builds: + # note: + # 1) do not include clean_fw and clean_core-dv because regression should be able to run parallel with different builds + # 2) every yaml should have unique build so that the parallel regressions from diff yaml file have no conflicts + # 3) cov is disabled by default and should be explicitely enabled with command switch --cov + # 4) fixme: iss is disabled by default and should be explcitely enabled with command switch --iss=yes (maybe enable by default is better, to be decided later) + # 5) num is default as minimum and should be explicitely enabled with command switch --num= + + # 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 + # cov: 0 + uvmt_cv32e40p_pulp_fpu: + cmd: make comp comp_corev-dv + dir: cv32e40p/sim/uvmt + cfg: pulp_fpu + uvmt_cv32e40p_pulp_fpu_1cyclat: + cmd: make comp comp_corev-dv + dir: cv32e40p/sim/uvmt + cfg: pulp_fpu_1cyclat + uvmt_cv32e40p_pulp_fpu_2cyclat: + cmd: make comp comp_corev-dv + dir: cv32e40p/sim/uvmt + cfg: pulp_fpu_2cyclat + +# ==================================================================================== +# LIST OF TESTS + +# ==================================================================================== +# V2 PULP tests +# ==================================================================================== +# ----------------------------------------------------------------------------------- +tests: + # ----------------------------------------------------------------------------------- + # corev_rand_pulp_hwloop_test + corev_rand_pulp_hwloop_test_floating_pt_instr_en: + testname: corev_rand_pulp_hwloop_test + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: corev_rand_pulp_hwloop_test with FPU enabled + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_hwloop_test + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_debug_ebreak_xpulp + corev_rand_debug_ebreak_xpulp_floating_pt_instr_en: + testname: corev_rand_debug_ebreak_xpulp + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: corev_rand_debug_ebreak_xpulp with FPU enabled + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_debug_ebreak_xpulp + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_debug_single_step_xpulp + corev_rand_debug_single_step_xpulp_floating_pt_instr_en: + testname: corev_rand_debug_single_step_xpulp + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: corev_rand_debug_single_step_xpulp + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_debug_single_step_xpulp + iss: 1 + + + # ==================================================================================== + # V1 rand tests re-used with v2 features + # ==================================================================================== + # ----------------------------------------------------------------------------------- + # corev_rand_instr_long_stall + corev_rand_instr_long_stall_floating_pt_instr_en: + testname: corev_rand_instr_long_stall + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: corev_rand_instr_long_stall + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_instr_long_stall + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_interrupt + corev_rand_interrupt_floating_pt_instr_en: + testname: corev_rand_interrupt + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: corev_rand_interrupt + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_interrupt_debug + corev_rand_interrupt_debug_floating_pt_instr_en: + testname: corev_rand_interrupt_debug + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: corev_rand_interrupt_debug + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_debug + iss: 1 + + corev_rand_interrupt_exception: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: corev_rand_interrupt_exception + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_exception + iss: 1 + + corev_rand_interrupt_nested: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: corev_rand_interrupt_nested + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_nested + iss: 1 + + corev_rand_interrupt_wfi_mem_stress: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: corev_rand_interrupt_wfi_mem_stress + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_wfi_mem_stress + iss: 1 + + corev_rand_jump_stress_test: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: corev_rand_jump_stress_test + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_jump_stress_test + iss: 1 + + +# ==================================================================================== +# V1 test re-used +# ==================================================================================== +# ----------------------------------------------------------------------------------- + hello-world: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: uvm_hello_world_test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=hello-world + iss: 1 + + hpmcounter_basic_test: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Hardware performance counter basic test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=hpmcounter_basic_test + iss: 1 + + hpmcounter_hazard_test: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Hardware performance counter hazard test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=hpmcounter_hazard_test + iss: 1 + + riscv_ebreak_test_0: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Static corev-dv ebreak + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=riscv_ebreak_test_0 + iss: 1 + + riscv_arithmetic_basic_test_0: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Static riscv-dv arithmetic test 0 + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=riscv_arithmetic_basic_test_0 + iss: 1 + + riscv_arithmetic_basic_test_1: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Static riscv-dv arithmetic test 1 + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=riscv_arithmetic_basic_test_1 + iss: 1 + + illegal: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Illegal-riscv-tests + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=illegal + iss: 1 + + fibonacci: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Fibonacci test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=fibonacci + iss: 1 + + misalign: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Misalign test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=misalign + iss: 1 + + dhrystone: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Dhrystone test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=dhrystone + iss: 1 + + debug_test: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Debug Test 1 + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test + iss: 1 + + debug_test_reset: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Debug reset test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_reset + iss: 1 + + debug_test_trigger: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Debug trigger test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_trigger + iss: 1 + + debug_test_known_miscompares: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Debug test which contains known miscompares + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_known_miscompares + iss: 0 + + debug_test_boot_set: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Debug test target debug_req at BOOT_SET + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_boot_set + iss: 1 + + interrupt_bootstrap: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Interrupt bootstrap test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=interrupt_bootstrap + iss: 1 + + interrupt_test: + builds: + - uvmt_cv32e40p_pulp_fpu + - uvmt_cv32e40p_pulp_fpu_1cyclat + - uvmt_cv32e40p_pulp_fpu_2cyclat + description: Interrupt test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=interrupt_test + iss: 1 diff --git a/cv32e40p/regress/cv32e40pv2_full_unique_bld3.yaml b/cv32e40p/regress/cv32e40pv2_full_unique_bld3.yaml new file mode 100644 index 0000000000..6dade866ed --- /dev/null +++ b/cv32e40p/regress/cv32e40pv2_full_unique_bld3.yaml @@ -0,0 +1,344 @@ +# Copyright 2023 Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# YAML file to specify a regression testlist +# Note that the COREV=YES is set for all tests in this regression. +# This means you need to have a toolchain at COREV_SW_TOOLCHAIN (see Common.mk) +--- +# Header +name: cv32_full_build +description: Regression list for most of the tests in CV32E40P with specific build(s) + +# List of builds +builds: + # note: + # 1) do not include clean_fw and clean_core-dv because regression should be able to run parallel with different builds + # 2) every yaml should have unique build so that the parallel regressions from diff yaml file have no conflicts + # 3) cov is disabled by default and should be explicitely enabled with command switch --cov + # 4) fixme: iss is disabled by default and should be explcitely enabled with command switch --iss=yes (maybe enable by default is better, to be decided later) + # 5) num is default as minimum and should be explicitely enabled with command switch --num= + + # 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 + # cov: 0 + uvmt_cv32e40p_pulp_fpu_zfinx: + cmd: make comp comp_corev-dv + dir: cv32e40p/sim/uvmt + cfg: pulp_fpu_zfinx + uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat: + cmd: make comp comp_corev-dv + dir: cv32e40p/sim/uvmt + cfg: pulp_fpu_zfinx_1cyclat + uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat: + cmd: make comp comp_corev-dv + dir: cv32e40p/sim/uvmt + cfg: pulp_fpu_zfinx_2cyclat + +# ==================================================================================== +# LIST OF TESTS + +# ==================================================================================== +# V2 PULP tests +# ==================================================================================== +# ----------------------------------------------------------------------------------- +tests: + # ----------------------------------------------------------------------------------- + # corev_rand_pulp_hwloop_test + corev_rand_pulp_hwloop_test_floating_pt_instr_en: + testname: corev_rand_pulp_hwloop_test + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: corev_rand_pulp_hwloop_test with FPU enabled + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_hwloop_test + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_debug_ebreak_xpulp + corev_rand_debug_ebreak_xpulp_floating_pt_instr_en: + testname: corev_rand_debug_ebreak_xpulp + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: corev_rand_debug_ebreak_xpulp with FPU enabled + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_debug_ebreak_xpulp + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_debug_single_step_xpulp + corev_rand_debug_single_step_xpulp_floating_pt_instr_en: + testname: corev_rand_debug_single_step_xpulp + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: corev_rand_debug_single_step_xpulp + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_debug_single_step_xpulp + iss: 1 + + + # ==================================================================================== + # V1 rand tests re-used with v2 features + # ==================================================================================== + # ----------------------------------------------------------------------------------- + # corev_rand_instr_long_stall + corev_rand_instr_long_stall_floating_pt_instr_en: + testname: corev_rand_instr_long_stall + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: corev_rand_instr_long_stall + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_instr_long_stall + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_interrupt + corev_rand_interrupt_floating_pt_instr_en: + testname: corev_rand_interrupt + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: corev_rand_interrupt + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt + iss: 1 + + # ----------------------------------------------------------------------------------- + # corev_rand_interrupt_debug + corev_rand_interrupt_debug_floating_pt_instr_en: + testname: corev_rand_interrupt_debug + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: corev_rand_interrupt_debug + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_debug + iss: 1 + + corev_rand_interrupt_exception: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: corev_rand_interrupt_exception + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_exception + iss: 1 + + corev_rand_interrupt_nested: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: corev_rand_interrupt_nested + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_nested + iss: 1 + + corev_rand_interrupt_wfi_mem_stress: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: corev_rand_interrupt_wfi_mem_stress + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_wfi_mem_stress + iss: 1 + + corev_rand_jump_stress_test: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: corev_rand_jump_stress_test + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_jump_stress_test + iss: 1 + + +# ==================================================================================== +# V1 test re-used +# ==================================================================================== +# ----------------------------------------------------------------------------------- + hello-world: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: uvm_hello_world_test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=hello-world + iss: 1 + + hpmcounter_basic_test: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Hardware performance counter basic test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=hpmcounter_basic_test + iss: 1 + + hpmcounter_hazard_test: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Hardware performance counter hazard test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=hpmcounter_hazard_test + iss: 1 + + riscv_ebreak_test_0: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Static corev-dv ebreak + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=riscv_ebreak_test_0 + iss: 1 + + riscv_arithmetic_basic_test_0: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Static riscv-dv arithmetic test 0 + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=riscv_arithmetic_basic_test_0 + iss: 1 + + riscv_arithmetic_basic_test_1: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Static riscv-dv arithmetic test 1 + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=riscv_arithmetic_basic_test_1 + iss: 1 + + illegal: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Illegal-riscv-tests + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=illegal + iss: 1 + + fibonacci: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Fibonacci test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=fibonacci + iss: 1 + + misalign: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Misalign test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=misalign + iss: 1 + + dhrystone: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Dhrystone test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=dhrystone + iss: 1 + + debug_test: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Debug Test 1 + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test + iss: 1 + + debug_test_reset: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Debug reset test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_reset + iss: 1 + + debug_test_trigger: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Debug trigger test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_trigger + iss: 1 + + debug_test_known_miscompares: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Debug test which contains known miscompares + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_known_miscompares + iss: 0 + + debug_test_boot_set: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Debug test target debug_req at BOOT_SET + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_boot_set + iss: 1 + + interrupt_bootstrap: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Interrupt bootstrap test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=interrupt_bootstrap + iss: 1 + + interrupt_test: + builds: + - uvmt_cv32e40p_pulp_fpu_zfinx + - uvmt_cv32e40p_pulp_fpu_zfinx_1cyclat + - uvmt_cv32e40p_pulp_fpu_zfinx_2cyclat + description: Interrupt test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=interrupt_test + iss: 1 diff --git a/cv32e40p/regress/cv32e40pv2_interrupt_debug.yaml b/cv32e40p/regress/cv32e40pv2_interrupt_debug.yaml new file mode 100644 index 0000000000..3e4c26aada --- /dev/null +++ b/cv32e40p/regress/cv32e40pv2_interrupt_debug.yaml @@ -0,0 +1,154 @@ +# Copyright 2023 Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# Header +name: cv32e40pv2_interrupt_debug +description: regression for CV32E40Pv2, focused on debug and interrupt tests + +# 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_rand_debug: + build: uvmt_cv32e40p + description: corev_rand_debug + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_debug CFG_PLUSARGS="+UVM_TIMEOUT=20000000" + + corev_rand_debug_ebreak: + build: uvmt_cv32e40p + description: corev_rand_debug_ebreak + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_debug_ebreak CFG_PLUSARGS="+UVM_TIMEOUT=20000000" + test_cfg: debug_ebreak + + corev_rand_debug_ebreak_xpulp: + build: uvmt_cv32e40p + description: corev_rand_debug_ebreak_xpulp + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_debug_ebreak_xpulp + test_cfg: debug_ebreak + + corev_rand_debug_single_step: + build: uvmt_cv32e40p + description: corev_rand_debug_single_step + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_debug_single_step CFG_PLUSARGS="+UVM_TIMEOUT=20000000" + test_cfg: debug_single_step_en + + corev_rand_debug_single_step_xpulp: + build: uvmt_cv32e40p + description: corev_rand_debug_single_step_xpulp + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_debug_single_step_xpulp CFG_PLUSARGS="+UVM_TIMEOUT=20000000" + test_cfg: debug_single_step_en + + corev_rand_interrupt: + build: uvmt_cv32e40p + description: corev_rand_interrupt + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt CFG_PLUSARGS="+UVM_TIMEOUT=20000000" + + corev_rand_interrupt_debug: + build: uvmt_cv32e40p + description: corev_rand_interrupt_debug + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_debug CFG_PLUSARGS="+UVM_TIMEOUT=20000000" + + corev_rand_interrupt_exception: + build: uvmt_cv32e40p + description: corev_rand_interrupt_exception + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_exception CFG_PLUSARGS="+UVM_TIMEOUT=20000000" + + corev_rand_interrupt_nested: + build: uvmt_cv32e40p + description: corev_rand_interrupt_nested + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_nested CFG_PLUSARGS="+UVM_TIMEOUT=20000000" + + corev_rand_interrupt_wfi: + build: uvmt_cv32e40p + description: corev_rand_interrupt_wfi + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_wfi CFG_PLUSARGS="+UVM_TIMEOUT=20000000" + + corev_rand_interrupt_wfi_mem_stress: + build: uvmt_cv32e40p + description: corev_rand_interrupt_wfi_mem_stress + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_interrupt_wfi_mem_stress CFG_PLUSARGS="+UVM_TIMEOUT=20000000" + + corev_rand_pulp_hwloop_debug: + build: uvmt_cv32e40p + description: corev_rand_pulp_hwloop_debug + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_hwloop_debug + + debug_test: + build: uvmt_cv32e40p + description: debug_test (adapted from v1) + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test + num: 1 + + debug_test_boot_set: + build: uvmt_cv32e40p + description: debug_test_boot_set (adapted from v1) + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_boot_set + num: 1 + + debug_test_known_miscompares: + build: uvmt_cv32e40p + description: debug_test_known_miscompares (adapted from v1) + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_known_miscompares + num: 1 + + debug_test_reset: + build: uvmt_cv32e40p + description: debug_test_reset (adapted from v1) + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_reset + num: 1 + + debug_test_reset: + build: uvmt_cv32e40p + description: debug_test_reset (adapted from v1) + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=debug_test_reset + num: 1 + + interrupt_test: + build: uvmt_cv32e40p + description: interrupt_test (adapted from v1) + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=interrupt_test + num: 1 + + interrupt_bootstrap: + build: uvmt_cv32e40p + description: interrupt_bootstrap (adapted from v1) + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=interrupt_bootstrap + num: 1 + + riscv_ebreak_test_0: + build: uvmt_cv32e40p + description: riscv_ebreak_test_0 (adapted from v1) + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=riscv_ebreak_test_0 + num: 1 diff --git a/cv32e40p/regress/cv32e40pv2_xpulp_instr.yaml b/cv32e40p/regress/cv32e40pv2_xpulp_instr.yaml new file mode 100644 index 0000000000..44a6c61285 --- /dev/null +++ b/cv32e40p/regress/cv32e40pv2_xpulp_instr.yaml @@ -0,0 +1,207 @@ +# Copyright 2023 Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# Header +name: cv32e40pv2_pulp_instr +description: regression for CV32E40Pv2, focused on simple PULP instructions excluding hwloop, debug, interrupts, fpu instr, etc. + +# List of builds +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: + # ==================================================================================== + # V2 PULP tests + # ==================================================================================== + corev_rand_pulp_hwloop_test: + build: uvmt_cv32e40p + description: corev_rand_pulp_hwloop_test + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_hwloop_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" + + corev_rand_pulp_instr_test: + build: uvmt_cv32e40p + description: corev_rand_pulp_instr_test + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" + + corev_rand_pulp_simd_instr_test: + build: uvmt_cv32e40p + description: corev_rand_pulp_simd_instr_test + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_simd_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" + + corev_rand_pulp_mac_instr_test: + build: uvmt_cv32e40p + description: corev_rand_pulp_mac_instr_test + dir: cv32e40p/sim/uvmt + cmd: make gen_corev-dv test COREV=YES TEST=corev_rand_pulp_mac_instr_test CFG_PLUSARGS="+UVM_TIMEOUT=1000000" + + pulp_hardware_loop: + build: uvmt_cv32e40p + description: pulp_hardware_loop directed test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_hardware_loop + num: 1 + + pulp_hardware_loop_interrupt_test: + build: uvmt_cv32e40p + description: pulp_hardware_loop directed test + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_hardware_loop_interrupt_test + num: 1 + + # pulp_hardware_loop_debug_test: + # build: uvmt_cv32e40p + # description: pulp_hardware_loop directed test + # dir: cv32e40p/sim/uvmt + # cmd: make test COREV=YES TEST=pulp_hardware_loop_debug_test + # num: 1 + +# ==================================================================================== +# V1 legacy pulp tests +# ==================================================================================== + + pulp_bit_manipulation: + build: uvmt_cv32e40p + description: pulp_bit_manipulation legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_bit_manipulation + num: 1 + + pulp_general_alu: + build: uvmt_cv32e40p + description: pulp_general_alu legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_general_alu + num: 1 + + pulp_immediate_branching: + build: uvmt_cv32e40p + description: pulp_immediate_branching legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_immediate_branching + num: 1 + + pulp_multiply_accumulate: + build: uvmt_cv32e40p + description: pulp_multiply_accumulate legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_multiply_accumulate + num: 1 + + pulp_post_increment_load_store: + build: uvmt_cv32e40p + description: pulp_post_increment_load_store legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_post_increment_load_store + num: 1 + + pulp_vectorial_add_sub: + build: uvmt_cv32e40p + description: pulp_vectorial_add_sub legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_add_sub + num: 1 + + pulp_vectorial_avg: + build: uvmt_cv32e40p + description: pulp_vectorial_avg legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_avg + num: 1 + + pulp_vectorial_bit_manip: + build: uvmt_cv32e40p + description: pulp_vectorial_bit_manip legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_bit_manip + num: 1 + + pulp_vectorial_bitwise: + build: uvmt_cv32e40p + description: pulp_vectorial_bitwise legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_bitwise + num: 1 + + pulp_vectorial_comparison_1: + build: uvmt_cv32e40p + description: pulp_vectorial_comparison_1 legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_comparison_1 + num: 1 + + pulp_vectorial_comparison_2: + build: uvmt_cv32e40p + description: pulp_vectorial_comparison_2 legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_comparison_2 + num: 1 + + pulp_vectorial_comparison_3: + build: uvmt_cv32e40p + description: pulp_vectorial_comparison_3 legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_comparison_3 + num: 1 + + pulp_vectorial_complex: + build: uvmt_cv32e40p + description: pulp_vectorial_complex legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_complex + num: 1 + + pulp_vectorial_dot_product_1: + build: uvmt_cv32e40p + description: pulp_vectorial_dot_product_1 legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_dot_product_1 + num: 1 + + pulp_vectorial_dot_product_2: + build: uvmt_cv32e40p + description: pulp_vectorial_dot_product_2 legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_dot_product_2 + num: 1 + + pulp_vectorial_max: + build: uvmt_cv32e40p + description: pulp_vectorial_max legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_max + num: 1 + + pulp_vectorial_min: + build: uvmt_cv32e40p + description: pulp_vectorial_min legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_min + num: 1 + + pulp_vectorial_shift: + build: uvmt_cv32e40p + description: pulp_vectorial_shift legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_shift + num: 1 + + pulp_vectorial_shuffle_pack: + build: uvmt_cv32e40p + description: pulp_vectorial_shuffle_pack legacy v1, kept as it stresses corner cases + dir: cv32e40p/sim/uvmt + cmd: make test COREV=YES TEST=pulp_vectorial_shuffle_pack + num: 1 diff --git a/cv32e40p/sim/ExternalRepos.mk b/cv32e40p/sim/ExternalRepos.mk index c5cfc3baa8..999d600691 100644 --- a/cv32e40p/sim/ExternalRepos.mk +++ b/cv32e40p/sim/ExternalRepos.mk @@ -15,7 +15,7 @@ export SHELL = /bin/bash CV_CORE_REPO ?= https://github.com/openhwgroup/cv32e40p CV_CORE_BRANCH ?= dev -CV_CORE_HASH ?= 73ff0c15eef61cf7f1882dbf6f62ce5ada1216f3 +CV_CORE_HASH ?= 7e131050c88bd57b2866887eea7de07735f60706 CV_CORE_TAG ?= none # The CV_CORE_HASH above points to version of the RTL that is newer. diff --git a/cv32e40p/sim/tools/vsim/cov.tcl b/cv32e40p/sim/tools/vsim/cov.tcl index 9328cda29f..91153531b5 100644 --- a/cv32e40p/sim/tools/vsim/cov.tcl +++ b/cv32e40p/sim/tools/vsim/cov.tcl @@ -1 +1,3 @@ -coverage save -onexit -testname ${TEST}__${TEST_CONFIG}__${TEST_SEED} ${TEST}.ucdb +coverage attr -name TESTNAME -value [format "%s" $::env(TEST_COV)$::env(TEST_CFG_FILE_COV)__$::env(TEST_CONFIG_COV)__$::env(TEST_SEED_COV)] +coverage attr -test $::env(TEST_COV)_$::env(TEST_CFG_FILE_COV)__$::env(TEST_CONFIG_COV)__$::env(TEST_SEED_COV) +coverage save -onexit $::env(TEST_COV)$::env(TEST_CFG_FILE_COV).ucdb diff --git a/cv32e40p/tb/uvmt/uvmt_cv32e40p_imperas_riscv_coverage_config.svh b/cv32e40p/tb/uvmt/uvmt_cv32e40p_imperas_riscv_coverage_config.svh index fa41f9be30..84ae410b71 100644 --- a/cv32e40p/tb/uvmt/uvmt_cv32e40p_imperas_riscv_coverage_config.svh +++ b/cv32e40p/tb/uvmt/uvmt_cv32e40p_imperas_riscv_coverage_config.svh @@ -15,11 +15,28 @@ `define COVER_RV32M `define COVER_RV32C `define COVER_RVVI_METRICS + `ifdef FPU `ifndef ZFINX `define COVER_RV32F + `define COVER_RV32ZCF `else `define COVER_RV32ZFINX `endif + `else + `define COVER_RV32F_ILLEGAL + `define COVER_RV32ZCF_ILLEGAL + `endif + + `ifdef PULP + `define COVER_XPULPV2 + `ifdef CLUSTER + `define COVER_XPULPV2C + `else + `define COVER_XPULPV2C_ILLEGAL + `endif + `else + `define COVER_XPULPV2_ILLEGAL + `define COVER_XPULPV2C_ILLEGAL `endif `endif diff --git a/cv32e40p/tests/programs/corev-dv/corev_rand_fp_instr_data_fwd_test/corev-dv.yaml b/cv32e40p/tests/programs/corev-dv/corev_rand_fp_instr_data_fwd_test/corev-dv.yaml index 479750a008..163be4a13f 100644 --- a/cv32e40p/tests/programs/corev-dv/corev_rand_fp_instr_data_fwd_test/corev-dv.yaml +++ b/cv32e40p/tests/programs/corev-dv/corev_rand_fp_instr_data_fwd_test/corev-dv.yaml @@ -25,5 +25,5 @@ plusargs: > +num_of_sub_program=0 +test_override_riscv_instr_stream=1 +no_branch_jump=1 - +directed_instr_0=cv32e40p_fp_w_prev_rd_as_operand_instr_stream,2 + +directed_instr_0=cv32e40p_fp_w_prev_rd_as_operand_instr_stream,5 +directed_instr_1=cv32e40p_fp_operand_forwarding_instr_stream,3 diff --git a/cv32e40p/tests/programs/corev-dv/corev_rand_fp_instr_sanity_test/corev-dv.yaml b/cv32e40p/tests/programs/corev-dv/corev_rand_fp_instr_sanity_test/corev-dv.yaml index e91537973e..68d47a3b93 100644 --- a/cv32e40p/tests/programs/corev-dv/corev_rand_fp_instr_sanity_test/corev-dv.yaml +++ b/cv32e40p/tests/programs/corev-dv/corev_rand_fp_instr_sanity_test/corev-dv.yaml @@ -32,7 +32,6 @@ plusargs: > +directed_instr_4=cv32e40p_fp_w_prev_rd_as_operand_instr_stream,1 +directed_instr_5=cv32e40p_constraint_mc_fp_instr_stream,1 +directed_instr_6=cv32e40p_fp_operand_forwarding_instr_stream,1 - # +directed_instr_7=cv32e40p_fp_followed_by_csrr_instr_stream,1 # note: # 1) example yaml template for fp test with f_extension diff --git a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_debug/corev-dv.yaml b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_debug/corev-dv.yaml index ce0c87fdd0..6f9ee69c08 100644 --- a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_debug/corev-dv.yaml +++ b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_debug/corev-dv.yaml @@ -10,7 +10,14 @@ description: > plusargs: > +instr_cnt=1000 +num_of_sub_program=0 - +directed_instr_0=cv32e40p_xpulp_hwloop_base_stream,1 + +insert_rand_directed_instr_stream=1 + +test_rand_directed_instr_stream_num=6 + +rand_directed_instr_0=cv32e40p_xpulp_hwloop_base_stream,1 + +rand_directed_instr_1=cv32e40p_xpulp_hwloop_base_stream,1 + +rand_directed_instr_2=cv32e40p_xpulp_short_hwloop_stream,1 + +rand_directed_instr_3=cv32e40p_xpulp_long_hwloop_stream,1 + +rand_directed_instr_4=cv32e40p_xpulp_hwloop_isa_stress_stream,1 + +rand_directed_instr_5=cv32e40p_xpulp_hwloop_exception,1 +no_fence=1 +no_data_page=0 +randomize_csr=1 @@ -18,12 +25,11 @@ plusargs: > +boot_mode=m +no_csr_instr=0 +no_wfi=1 - +no_ebreak=1 +no_dret=1 +enable_misaligned_instr=1 +enable_ebreak_in_debug_rom=0 - +set_dcsr_ebreak=0 +test_override_riscv_instr_stream=1 +test_override_riscv_instr_sequence=1 - +enable_debug_single_step=0 +gen_debug_section=1 + +is_hwloop_test=1 + +include_xpulp_instr_in_debug_rom diff --git a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_exception/corev-dv.yaml b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_exception/corev-dv.yaml new file mode 100644 index 0000000000..0c1c203a3e --- /dev/null +++ b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_exception/corev-dv.yaml @@ -0,0 +1,26 @@ +# Copyright 2023 Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# Test definition YAML for corev-dv test generator +# corev-dv generator test +name: corev_rand_pulp_hwloop_test +uvm_test: $(CV_CORE_LC)_instr_base_test +description: > + RISCV-DV generated random hwloop test +plusargs: > + +instr_cnt=1000 + +num_of_sub_program=0 + +directed_instr_0=cv32e40p_xpulp_hwloop_exception,2 + +no_fence=0 + +no_data_page=0 + +randomize_csr=1 + +no_branch_jump=0 + +boot_mode=m + +no_csr_instr=0 + +no_wfi=1 + +no_ebreak=0 + +no_dret=1 + +enable_misaligned_instr=1 + +illegal_instr_ratio=5 + +test_override_riscv_instr_stream=1 + +test_override_riscv_instr_sequence=1 diff --git a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_exception/test.yaml b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_exception/test.yaml new file mode 100644 index 0000000000..60448684b4 --- /dev/null +++ b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_exception/test.yaml @@ -0,0 +1,9 @@ +# Copyright 2023 Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# Test definition YAML for random pulp hwloop exception test +name: corev_rand_pulp_hwloop_exception +uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c +description: > + Random hwloop test with exception +plusargs: > diff --git a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_test/corev-dv.yaml b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_test/corev-dv.yaml index c0ada3568f..faf4ab4a3d 100644 --- a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_test/corev-dv.yaml +++ b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_hwloop_test/corev-dv.yaml @@ -34,6 +34,5 @@ plusargs: > +no_dret=1 +enable_misaligned_instr=0 +set_dcsr_ebreak=0 - +enable_floating_point=1 +test_override_riscv_instr_stream=1 +test_override_riscv_instr_sequence=1 diff --git a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_instr_test/corev-dv.yaml b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_instr_test/corev-dv.yaml index d38dea68f7..3a58cd66f9 100644 --- a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_instr_test/corev-dv.yaml +++ b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_instr_test/corev-dv.yaml @@ -11,11 +11,10 @@ plusargs: > +instr_cnt=2000 +num_of_sub_program=0 +insert_rand_directed_instr_stream=1 - +test_rand_directed_instr_stream_num=8 + +test_rand_directed_instr_stream_num=9 +directed_instr_0=cv32e40p_xpulp_rand_stream,2 +directed_instr_1=cv32e40p_xpulp_short_rand_stream,4 - +directed_instr_2=riscv_int_numeric_corner_stream,2 - +directed_instr_3=riscv_load_store_rand_instr_stream,1 + +directed_instr_2=riscv_load_store_rand_instr_stream,1 +rand_directed_instr_0=riscv_load_store_rand_instr_stream,2 +rand_directed_instr_1=riscv_mem_region_stress_test,2 +rand_directed_instr_2=riscv_load_store_hazard_instr_stream,2 @@ -24,6 +23,7 @@ plusargs: > +rand_directed_instr_5=riscv_hazard_instr_stream,2 +rand_directed_instr_6=cv32e40p_xpulp_simd_stream_test,2 +rand_directed_instr_7=cv32e40p_xpulp_mac_stream_test,2 + +rand_directed_instr_8=riscv_int_numeric_corner_stream,2 +no_fence=0 +hint_instr_ratio=2 +no_data_page=0 @@ -32,10 +32,7 @@ plusargs: > +boot_mode=m +no_csr_instr=0 +no_wfi=1 - +no_ebreak=1 +no_dret=1 +enable_misaligned_instr=1 - +set_dcsr_ebreak=0 - +enable_floating_point=1 +test_override_riscv_instr_stream=1 +test_override_riscv_instr_sequence=1 diff --git a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_mac_instr_test/corev-dv.yaml b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_mac_instr_test/corev-dv.yaml index 3d5f74f3f4..37225b445e 100644 --- a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_mac_instr_test/corev-dv.yaml +++ b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_mac_instr_test/corev-dv.yaml @@ -32,6 +32,5 @@ plusargs: > +no_dret=1 +enable_misaligned_instr=1 +set_dcsr_ebreak=0 - +enable_floating_point=1 +test_override_riscv_instr_stream=1 +test_override_riscv_instr_sequence=1 diff --git a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_simd_instr_test/corev-dv.yaml b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_simd_instr_test/corev-dv.yaml index 959b39a4c1..45ade40084 100644 --- a/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_simd_instr_test/corev-dv.yaml +++ b/cv32e40p/tests/programs/corev-dv/corev_rand_pulp_simd_instr_test/corev-dv.yaml @@ -32,6 +32,5 @@ plusargs: > +no_dret=1 +enable_misaligned_instr=1 +set_dcsr_ebreak=0 - +enable_floating_point=1 +test_override_riscv_instr_stream=1 +test_override_riscv_instr_sequence=1 diff --git a/cv32e40p/tests/test_cfg/debug_ebreak.yaml b/cv32e40p/tests/test_cfg/debug_ebreak.yaml new file mode 100644 index 0000000000..5f911a8304 --- /dev/null +++ b/cv32e40p/tests/test_cfg/debug_ebreak.yaml @@ -0,0 +1,8 @@ +name: debug_ebreak +description: > + Config to gen ebreak instructions and set dcsr ebreakm +plusargs: > + +no_ebreak=0 + +set_dcsr_ebreak=1 + +enable_interrupt=1 + +enable_fast_interrupt_handler=1 diff --git a/cv32e40p/tests/test_cfg/gen_rand_int.yaml b/cv32e40p/tests/test_cfg/gen_rand_int.yaml new file mode 100644 index 0000000000..54500496b5 --- /dev/null +++ b/cv32e40p/tests/test_cfg/gen_rand_int.yaml @@ -0,0 +1,7 @@ +name: gen_interrupt +description: > + Enable and Trigger Interrupts +plusargs: > + +enable_interrupt=1 + +enable_fast_interrupt_handler=1 + +gen_irq_noise diff --git a/cv32e40p/tests/test_cfg/insert_illegal_instr.yaml b/cv32e40p/tests/test_cfg/insert_illegal_instr.yaml new file mode 100644 index 0000000000..f5e078ae7a --- /dev/null +++ b/cv32e40p/tests/test_cfg/insert_illegal_instr.yaml @@ -0,0 +1,5 @@ +name: insert_illegal_instr +description: > + Insert Illegal Instructions +plusargs: > + +illegal_instr_ratio=5 diff --git a/mk/Common.mk b/mk/Common.mk index b4b20fec84..e635788a84 100644 --- a/mk/Common.mk +++ b/mk/Common.mk @@ -254,13 +254,46 @@ endif # test_cfg CFGYAML2MAKE = $(CORE_V_VERIF)/bin/cfgyaml2make CFG_YAML_PARSE_TARGETS=comp ldgen comp_corev-dv gen_corev-dv test hex clean_hex corev-dv sanity-veri-run bsp riscof_sim_run -ifneq ($(filter $(CFG_YAML_PARSE_TARGETS),$(MAKECMDGOALS)),) ifneq ($(TEST_CFG_FILE),) -TEST_CFG_FLAGS_MAKE := $(shell $(CFGYAML2MAKE) --yaml=$(TEST_CFG_FILE).yaml $(YAML2MAKE_DEBUG) --prefix=TEST_CFG_FILE --core=$(CV_CORE)) -ifeq ($(TEST_CFG_FLAGS_MAKE),) -$(error ERROR Error finding or parsing configuration: $(TEST_CFG_FILE).yaml) +TEST_CFG_FILE_PLUSARGS = +SPACE_CHAR := $(subst ,, ) +COMMA_CHAR := , +PLUS_CHAR := + +TEST_CFG_FILE_TEMP_NAME := $(patsubst , ,$(TEST_CFG_FILE)) +ifneq (,$(findstring $(COMMA_CHAR),$(TEST_CFG_FILE_TEMP_NAME))) + TEST_CFG_FILE_LIST_TEMP := $(subst $(COMMA_CHAR), ,$(TEST_CFG_FILE_TEMP_NAME)) +else + ifneq (,$(findstring $(PLUS_CHAR),$(TEST_CFG_FILE_TEMP_NAME))) + TEST_CFG_FILE_LIST_TEMP := $(subst $(PLUS_CHAR), ,$(TEST_CFG_FILE_TEMP_NAME)) + else + TEST_CFG_FILE_LIST_TEMP := $(TEST_CFG_FILE_TEMP_NAME) + endif +endif + +TEST_CFG_FILE_LIST := $(sort $(TEST_CFG_FILE_LIST_TEMP)) +TEST_CFG_FILE_NAME = $(subst $(SPACE_CHAR),__,$(TEST_CFG_FILE_LIST)) + +ifneq ($(filter $(CFG_YAML_PARSE_TARGETS),$(MAKECMDGOALS)),) +ifneq ($(TEST_CFG_FILE_LIST),) + +define GET_TEST_CONFIG_LIST = +TEST_CFG_LIST_FLAGS_MAKE_$(1) := $$(shell $(CFGYAML2MAKE) --yaml=$(1).yaml $(YAML2MAKE_DEBUG) --prefix=TEST_CFG_FILE_LIST_$(1) --core=$(CV_CORE) --debug) +ifeq ($$(TEST_CFG_LIST_FLAGS_MAKE_$(1)),) + $$(error ERROR Error finding or parsing configuration: $(1).yaml) +endif +include $$(TEST_CFG_LIST_FLAGS_MAKE_$(1)) +TEST_CFG_FILE_PLUSARGS += $$(TEST_CFG_FILE_LIST_$(2)_PLUSARGS) +endef + +$(foreach TEST_CFG_FILE_IN_LIST,$(TEST_CFG_FILE_LIST), $(eval $(call GET_TEST_CONFIG_LIST,$(TEST_CFG_FILE_IN_LIST),$(shell echo $(TEST_CFG_FILE_IN_LIST) | tr '[:lower:]' '[:upper:]')))) + +$(info $(BANNER)) +$(info [INFO] Using TEST_CFG_FILE_LIST $(TEST_CFG_FILE_LIST)) +$(info [INFO] TEST_CFG dir name $(TEST_CFG_FILE_NAME)) +$(info [INFO] TEST_CFG_FILE plusargs $(TEST_CFG_FILE_PLUSARGS)) +$(info $(BANNER)) + endif -include $(TEST_CFG_FLAGS_MAKE) endif endif diff --git a/mk/README.md b/mk/README.md index 7ae064ca9e..7c97e7c75f 100644 --- a/mk/README.md +++ b/mk/README.md @@ -415,14 +415,24 @@ The following will increase the verbosity level to DEBUG. For a given test, test.yaml file would typically have all the relevant plusargs for that test, but in certain cases there are new features or updates added to TB, or there is a need to run all the tests with a new TB config, say for example a particular bus delay config. This would previously require to either update all existing tests with new plusargs, or add new tests just for this requirement. -Using this **TEST_CFG_FILE** allows us to retain all existing test setup while providing a simple mechanism to run those tests with additional configs, on top of the ones in test.yaml, passed through a separate yaml file provided using variable TEST_CFG_FILE with the make command. +Using this **TEST_CFG_FILE** allows us to retain all existing test setup while providing a simple mechanism to run those tests with additional configs, on top of the ones in test.yaml, passed through separate yaml file(s) provided using variable TEST_CFG_FILE with the make command. -This is different from above **USER_RUN_FLAGS** method, as this would also create a unique directory path, log names, coverage db etc. suffixed with TEST_CFG_FILE name, and hence this mechanism goes beyond the **USER_RUN_FLAGS** method in a sense that it provides a way to run tests through regression scripts as unique tests differentitated from same default TEST by TEST_CFG_FILE. And hence such tests can be also be rerun, for example in case of failing tests from regression report, without the knowledge of CMD line arguments such as the ones passed through USER_RUN_FLAGS mechanism. +This is different from above **USER_RUN_FLAGS** method, as this would also create a unique directory path, log names, coverage db etc. suffixed with unique name based on TEST_CFG_FILE arguments, and hence this mechanism goes beyond the **USER_RUN_FLAGS** method in a sense that it provides a way to run tests through regression scripts as unique tests differentitated from same default TEST by TEST_CFG_FILE. And hence such tests can be also be rerun, for example in case of failing tests from regression report, without the knowledge of CMD line arguments such as the ones passed through USER_RUN_FLAGS mechanism. + +TEST_CFG_FILE can take multiple yaml files as input. Such multiple yaml file can be provided by adding separators "," or "+" or a "whitespace" Example: **make gen_corev-dv test TEST=corev_rand_arithmetic_base_test USE_ISS=no CFG=pulp_fpu WAVES=1 SEED=random TEST_CFG_FILE=floating_pt_instr_en** +**make gen_corev-dv test TEST=corev_rand_arithmetic_base_test USE_ISS=no CFG=pulp_fpu WAVES=1 SEED=random TEST_CFG_FILE=floating_pt_instr_en,debug_ebreak** + +**make gen_corev-dv test TEST=corev_rand_arithmetic_base_test USE_ISS=no CFG=pulp_fpu WAVES=1 SEED=random TEST_CFG_FILE=floating_pt_instr_en,debug_ebreak,insert_illegal_instr** + +**make gen_corev-dv test TEST=corev_rand_arithmetic_base_test USE_ISS=no CFG=pulp_fpu WAVES=1 SEED=random TEST_CFG_FILE=floating_pt_instr_en+debug_ebreak** + +**make gen_corev-dv test TEST=corev_rand_arithmetic_base_test USE_ISS=no CFG=pulp_fpu WAVES=1 SEED=random TEST_CFG_FILE="floating_pt_instr_en debug_ebreak"** + ### Post-process Waveform Debug There are flags and targets defined to support generating waveforms during simulation and viewing those waveforms in a post-process debug tool specific to the respective simulator used.
diff --git a/mk/uvmt/uvmt.mk b/mk/uvmt/uvmt.mk index 6d3e1889f9..b04d9bc6b5 100644 --- a/mk/uvmt/uvmt.mk +++ b/mk/uvmt/uvmt.mk @@ -95,10 +95,10 @@ export RUN_INDEX ?= 0 # Common test runtime plusargs from external file, used as test-configuration # Test Name with test-configuration -TEST_RUN_NAME = $(if $(TEST_CFG_FILE),$(TEST)_$(TEST_CFG_FILE),$(TEST)) -# Build unique _suffix based on TEST_CFG_FILE, for unique test log files and ucdb file names -ifneq ($(TEST_CFG_FILE),) -export TEST_CFG_FILE_SUFFIX=_$(TEST_CFG_FILE) +TEST_RUN_NAME = $(if $(TEST_CFG_FILE_NAME),$(TEST)_$(TEST_CFG_FILE_NAME),$(TEST)) +# Build unique _suffix based on TEST_CFG_FILE_NAME, for unique test log files and ucdb file names +ifneq ($(TEST_CFG_FILE_NAME),) +export TEST_CFG_FILE_SUFFIX=_$(TEST_CFG_FILE_NAME) endif # Common output directories @@ -106,7 +106,7 @@ SIM_RESULTS ?= $(if $(CV_RESULTS),$(abspath $(CV_RESULTS))/$(SIMULAT SIM_CFG_RESULTS = $(SIM_RESULTS)/$(CFG) SIM_COREVDV_RESULTS = $(SIM_CFG_RESULTS)/corev-dv SIM_LDGEN_RESULTS = $(SIM_CFG_RESULTS)/$(LDGEN) -SIM_TEST_RESULTS = $(if $(TEST_CFG_FILE),$(SIM_CFG_RESULTS)/$(TEST)/$(TEST_CFG_FILE),$(SIM_CFG_RESULTS)/$(TEST)) +SIM_TEST_RESULTS = $(if $(TEST_CFG_FILE_NAME),$(SIM_CFG_RESULTS)/$(TEST)/$(TEST_CFG_FILE_NAME),$(SIM_CFG_RESULTS)/$(TEST)) SIM_RUN_RESULTS = $(SIM_TEST_RESULTS)/$(RUN_INDEX) SIM_TEST_PROGRAM_RESULTS = $(SIM_RUN_RESULTS)/test_program SIM_BSP_RESULTS = $(SIM_TEST_PROGRAM_RESULTS)/bsp @@ -187,6 +187,7 @@ export TBSRC_HOME = $(CORE_V_VERIF)/$(CV_CORE_LC)/tb SIM_LIBS := $(CORE_V_VERIF)/lib/sim_libs +RTLSRC_VLOG_CORE_TOP := $(CV_CORE_LC)_top RTLSRC_VLOG_TB_TOP := $(basename $(notdir $(TBSRC_TOP))) RTLSRC_VOPT_TB_TOP := $(addsuffix _vopt, $(RTLSRC_VLOG_TB_TOP)) diff --git a/mk/uvmt/vsim.mk b/mk/uvmt/vsim.mk index 592f264ba7..b3bb220353 100644 --- a/mk/uvmt/vsim.mk +++ b/mk/uvmt/vsim.mk @@ -22,26 +22,32 @@ ############################################################################### # Executables -VLIB = vlib -VMAP = vmap -VLOG = $(CV_SIM_PREFIX) vlog -VOPT = $(CV_SIM_PREFIX) vopt -VSIM = $(CV_SIM_PREFIX) vsim -VISUALIZER = $(CV_TOOL_PREFIX) visualizer +VLIB = vlib +VMAP = vmap +VLOG = $(CV_SIM_PREFIX) vlog +VOPT = $(CV_SIM_PREFIX) vopt +VSIM = $(CV_SIM_PREFIX) vsim +VISUALIZER = $(CV_TOOL_PREFIX) visualizer VCOVER = vcover # Paths -VWORK = work +VWORK = work VSIM_COV_MERGE_DIR = $(SIM_CFG_RESULTS)/merged -UVM_HOME ?= $(abspath $(shell which $(VLIB))/../../verilog_src/uvm-1.2/src) -DPI_INCLUDE ?= $(abspath $(shell which $(VLIB))/../../include) +UVM_HOME ?= $(abspath $(shell which $(VLIB))/../../verilog_src/uvm-1.2/src) +DPI_INCLUDE ?= $(abspath $(shell which $(VLIB))/../../include) USES_DPI = 1 # Default flags +VSIM_COV_ONLY_PASS_TEST ?= YES VSIM_LOCAL_MODELSIMINI ?= YES +VOPT_CODE_COV_DUT_ONLY ?= YES VSIM_USER_FLAGS ?= -VOPT_COV ?= +cover=setf+$(RTLSRC_VLOG_TB_TOP). -VSIM_COV ?= -coverage +ifeq ($(call IS_YES,$(VOPT_CODE_COV_DUT_ONLY)),YES) +VOPT_COV ?= +cover=bcsetf+$(RTLSRC_VLOG_CORE_TOP). +else +VOPT_COV ?= +cover=setf+$(RTLSRC_VLOG_TB_TOP). +endif +VSIM_COV ?= -coverage VOPT_WAVES_ADV_DEBUG ?= -designfile design.bin VSIM_WAVES_ADV_DEBUG ?= -qwavedb=+signal+assertion+ignoretxntime+msgmode=both VSIM_WAVES_DO ?= $(VSIM_SCRIPT_DIR)/waves.tcl @@ -197,7 +203,7 @@ VSIM_COREVDV_SIM_PREREQ = comp_corev-dv endif # option to use local modelsim.ini file -ifeq ($(call IS_NO,$(VSIM_LOCAL_MODELSIMINI)),YES) +ifeq ($(call IS_YES,$(VSIM_LOCAL_MODELSIMINI)),YES) gen_corev-dv: VSIM_FLAGS += -modelsimini $(SIM_COREVDV_RESULTS)/modelsim.ini run: VSIM_FLAGS += -modelsimini modelsim.ini endif @@ -207,7 +213,12 @@ endif ifeq ($(call IS_YES,$(COV)),YES) VOPT_FLAGS += $(VOPT_COV) VSIM_FLAGS += $(VSIM_COV) -VSIM_FLAGS += -do 'set TEST ${VSIM_TEST}; set TEST_CONFIG $(CFG); set TEST_SEED $(RNDSEED); source $(VSIM_SCRIPT_DIR)/cov.tcl' +# VSIM_FLAGS += -do 'set TEST ${VSIM_TEST}; set TEST_CONFIG $(CFG); set TEST_SEED $(RNDSEED); source $(VSIM_SCRIPT_DIR)/cov.tcl' +ifneq ($(TEST_CFG_FILE_NAME),) +VSIM_FLAGS += -do 'setenv TEST_COV ${TEST}; setenv TEST_CONFIG_COV $(CFG); setenv TEST_CFG_FILE_COV _$(TEST_CFG_FILE_NAME); setenv TEST_SEED_COV $(RNDSEED); source $(VSIM_SCRIPT_DIR)/cov.tcl' +else +VSIM_FLAGS += -do 'setenv TEST_COV ${TEST}; setenv TEST_CONFIG_COV $(CFG); setenv TEST_CFG_FILE_COV ""; setenv TEST_SEED_COV $(RNDSEED); source $(VSIM_SCRIPT_DIR)/cov.tcl' +endif endif ################################################################################ @@ -244,8 +255,8 @@ endif COV_FLAGS = COV_REPORT = cov_report COV_MERGE_TARGET = -COV_MERGE_FIND = find $(SIM_RESULTS) -type f -name "*.ucdb" | grep -v merged.ucdb -COV_MERGE_FLAGS=merge -testassociated -verbose -64 -out merged.ucdb -inputs ucdb.list +COV_MERGE_FIND = find $(SIM_CFG_RESULTS) -type f -name "*.ucdb" -exec echo {} > $(VSIM_COV_MERGE_DIR)/ucdb.list \; +COV_MERGE_FLAGS = merge -testassociated -verbose -64 -out merged.ucdb -inputs ucdb.list ifeq ($(call IS_YES,$(MERGE)),YES) COV_DIR=$(VSIM_COV_MERGE_DIR) @@ -272,15 +283,32 @@ endif endif endif -ifeq ($(call IS_YES,$(CHECK_SIM_RESULT)),YES) +# to filter out failing test from ucdb merging +ifeq ($(call IS_YES,$(COV)),YES) +ifeq ($(call IS_YES,$(VSIM_COV_ONLY_PASS_TEST)),YES) +COV_TEST = cd $(RUN_DIR) && $(VSIM) -c -viewcov $(TEST_RUN_NAME).ucdb -do "coverage clear; coverage attr -name TESTSTATUS -value 2; coverage save $(TEST_RUN_NAME).ucdb; exit " ; +# COV_TEST = mv $(RUN_DIR)/$(TEST_RUN_NAME).ucdb $(RUN_DIR)/$(TEST_RUN_NAME).ucdb_FAIL; +else +COV_TEST = :; +endif +else +COV_TEST = :; +endif + +################################################################################ +# Check simulation log +#ifeq ($(call IS_YES,$(CHECK_SIM_RESULT)),YES) OR ifeq ($(call IS_YES,$(COV)),YES) +ifneq ($(filter YES, $(call IS_YES,$(CHECK_SIM_RESULT)) $(call IS_YES,$(COV))),) POST_TEST = \ @if grep -q "Errors:\s\+0" $(RUN_DIR)/vsim-$(VSIM_TEST).log; then \ - if grep -q "SIMULATION FAILED" $(RUN_DIR)/vsim-$(VSIM_TEST).log; then \ - exit 1; \ - else \ - exit 0; \ - fi \ + if grep -q "SIMULATION PASSED" $(RUN_DIR)/vsim-$(VSIM_TEST).log; then \ + exit 0; \ + else \ + $(COV_TEST) \ + exit 1; \ + fi \ else \ + $(COV_TEST) \ exit 1; \ fi endif @@ -688,10 +716,9 @@ waves: cov_merge: $(MKDIR_P) $(VSIM_COV_MERGE_DIR) cd $(VSIM_COV_MERGE_DIR) && \ - $(COV_MERGE_FIND) > $(VSIM_COV_MERGE_DIR)/ucdb.list + $(COV_MERGE_FIND) cd $(VSIM_COV_MERGE_DIR) && \ - $(VCOVER) \ - $(COV_MERGE_FLAGS) + [ -s $(VSIM_COV_MERGE_DIR)/ucdb.list ] && $(VCOVER) $(COV_MERGE_FLAGS) || echo "ucdb.list is empty" cov: $(COV_MERGE_TARGET) cd $(COV_DIR) && \ $(VSIM) \