diff --git a/hw/dv/tools/dvsim/sim.mk b/hw/dv/tools/dvsim/sim.mk index bd03c81d28a58..d673b883c0d88 100644 --- a/hw/dv/tools/dvsim/sim.mk +++ b/hw/dv/tools/dvsim/sim.mk @@ -38,7 +38,7 @@ do_build: gen_sv_flist post_build: do_build @echo "[make]: post_build" ifneq (${post_build_cmds},) - cd ${build_dir} && ${post_build_cmds} + cd ${build_dir} && ${post_build_cmds} ${post_build_opts} endif build_result: post_build @@ -183,7 +183,11 @@ endif simulate: sw_build @echo "[make]: simulate" +ifeq (${SIMULATOR}, z01x) + cd ${run_dir} && ${run_cmd} ${fi_sim_run_opts} +else cd ${run_dir} && ${run_cmd} ${run_opts} +endif post_run: simulate @echo "[make]: post_run" diff --git a/hw/dv/tools/dvsim/z01x.hjson b/hw/dv/tools/dvsim/z01x.hjson new file mode 100644 index 0000000000000..293fc1d15831e --- /dev/null +++ b/hw/dv/tools/dvsim/z01x.hjson @@ -0,0 +1,401 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + build_cmd: "{job_prefix} vcs" + post_build_cmds: ["{job_prefix} vc_fcc"] + build_ex: "{build_dir}/simv" + run_cmd: "{job_prefix} vc_fcm" + + fi_campaign: "fc_{name}" + fi_testcase: "tc_{name}" + fi_project: "fdb_{name}" + + // This option enables the following: (needed for uvm_hdl_*) + // - Read capability on registers, variables, and nets + // - Write (deposit) capability on registers and variables + // - Force capability on registers, variables, and nets + // TODO Trim this flag since +f hurts performance. + vcs_build_opt_debug_access: "-debug_access+f" + vcs_build_opt_debug_region: "-debug_region=cell+lib" + post_flist_opts: "" + build_opts: ["-sverilog -full64 -licqueue -ntb_opts uvm-1.2", + // Fault Injection specific parameters. + "-fsim=class {build_dir}/fusesoc-work/src/{strobe_file}", + "-fsim=dut:{dut_instance}", + "-fsim=portfaults", + "-assert disable_assert", + // General parameters. + "-timescale={timescale}", + "-Mdir={build_ex}.csrc", + "-o {build_ex}", + "-f {sv_flist}", + "{post_flist_opts}", + // Enable LCA features. It does not require separate licenses. + "-lca", + // List multiple tops for the simulation. Prepend each top level with `-top`. + "{eval_cmd} echo {sim_tops} | sed -E 's/(\\S+)/-top \\1/g'", + "+incdir+{build_dir}", + // Turn on warnings for non-void functions called with return values ignored + "+warn=SV-NFIVC", + "+warn=noUII-L", + // Disable unnecessary LCA warning. + "+warn=noLCA_FEATURES_ENABLED", + // Disable warnings about bind directive not being applied. + "+warn=noBNA", + // Below option required for $error/$fatal system calls + "-assert svaext", + // Force unique and priority to evaluate compliance checking only on the stable + // and final value of the selection input at the end of a simulation timestep. + // See https://github.com/lowRISC/ibex/issues/845. + "-xlrm uniq_prior_final", + // Newer compiler versions have escalated these warnings into an error by default, and + // VCS generates code to build the simulation executable which fails these checks. + // De-escalate the error (only when building the simv itself.) + // > rmapats.c:20:9: error: implicit declaration of function 'vcs_simpSetEBlkEvtID' + // > [-Wimplicit-function-declaration] + // > rmapats.c:466:36: error: passing argument 1 of 'setChildClockWriteFuncAndPcode' makes + // > integer from pointer without a cast + // > [-Wint-conversion] + "-Xcflags='-Wno-error=implicit-function-declaration -Wno-error=int-conversion'", + // Force DPI-C compilation in C99 mode. The -fno-extended-identifiers flag tells g++ + // not to worry about unicode. For some bizarre reason, the VCS DPI code contains + // preprocessor macros with smart quotes, which causes GCC 10.2 and later to choke + // otherwise. The double-escaped quotes are because this needs to go inside a string + // that gets passed to Make (stripping one level of quotes), and then needs to + // result in an argument with an embedded space (the other one). + "-CFLAGS --std=c99 -CFLAGS -fno-extended-identifiers", + // C++17 standard is enforced for all sources, including the DPI-C constructs. + // Refer to + // https://opentitan.org/book/doc/contributing/style_guides/c_cpp_coding_style.html#c-style-guide + "-CFLAGS --std=c++17", + // Without this magic LDFLAGS argument below, we get compile time errors with + // VCS on Google Linux machines that look like this: + // .../libvcsnew.so: undefined reference to `snpsReallocFunc' + // .../libvcsnew.so: undefined reference to `snpsCheckStrdupFunc' + // .../libvcsnew.so: undefined reference to `snpsGetMemBytes' + "-LDFLAGS -Wl,--no-as-needed", + // This option is needed for uvm_hdl_*, when it accesses the array under `celldefine + "{vcs_build_opt_debug_region}", + "{vcs_build_opt_debug_access}", + // Use this to conditionally compile for VCS (example: LRM interpretations differ + // across tools). + "+define+VCS", + // Upgrade below warnings to errors to make VCS more strict on syntax to avoid + // having issue with other simulators but passing with VCS + // + // Identifier previously declared + "-error=IPDW", + // Input Supply Port with no driver + "-error=UPF_ISPND", + // Invalid generic or parameter assignment + "-error=IGPA", + // Class scope used outside of class + "-error=PCSRMIO", + // Attempt to override undefined parameter + "-error=AOUP", + // Unbound component + "-error=ELW_UNBOUND", + // Illegal Use of Wildcard Index + "-error=IUWI", + // Index into non-array variable + "-error=INAV", + // Illegal Static Cast + "-error=SV-ISC", + // Obsolete System Verilog feature + "-error=OSVF-NPVIUFPI", + // Duplicate port in module instantiation + "-error=DPIMI", + // Identifier in ANSI port declaration + "-error=IPDASP", + // File not found + "-error=CM-HIER-FNF", + // Concatenations with unsized constants + "-error=CWUC", + // More arguments than needed + "-error=MATN", + // Specifying negative delays is invalid + "-error=STASKW_NDTAZ1", + // Too many parameter overrides + "-error=TMPO", + // Class objects must not hide other class members due to same name + "-error=SV-OHCM", + // ENUMASSIGN issues can cause LEC warnings later down the road (see #10083 + // and #10952 for context). The warning is therefore promoted to an error + // in simulations in order to catch this as early as possible. + "-error=ENUMASSIGN", + // Tasks must not be enabled in functions. Other tools do not allow this. + "-error=TEIF" + // This helps avoid races in flops per Synopsys CASE 01552811. + // It causes flops to always use the sampled data value. + "-deraceclockdata" + ] + post_build_opts: ["-full64", + "-daidir={build_ex}.daidir", + "-dut={dut_instance}", + "-overwrite", + "-fdb_project={fi_project}", + "-sff={build_dir}/fusesoc-work/src/{project_sff_file},{build_dir}/fusesoc-work/src/{block_sff_file}", + "-campaign={fi_campaign}", + "-fdb_path={build_dir}/fdb" + ] + + run_opts_fi_sim: ["-tcl_script={run_script}", + "-fdb_path={build_dir}/fdb" + "-fdb_project={fi_project}", + "-fc={fi_campaign}", + "-connect" + ] + + run_opts: ["-licqueue", + "+UVM_NO_RELNOTES +UVM_VERBOSITY=UVM_LOW", + // In VCS, all random generation starts with an initial seed and that remains same + // for each instance of the module. Hence, for each instance of the same module + // $urandom() generates same random value. + // Below switch generates different randomization values per instance of a module. + // Refer to https://github.com/lowRISC/opentitan/issues/27659 for more details. + "-xlrm hier_inst_seed", + // Disable the display of the SystemVerilog assert and cover statement summary + // at the end of simulation. This summary is list of assertions that started but + // did not finish because the simulation terminated, or assertions that did not + // fire at all. The latter is analyzed anyway in the collected coverage. Neither + // of these is useful in regular simulations. + "-assert nopostproc", + "+UVM_TESTNAME={uvm_test}", + "-assert disable_assert" + ] + + // Supported wave dumping formats (in order of preference). + supported_wave_formats: ["fsdb", "vpd"] + + // Default tcl script used when running the sim. Override if needed. + run_script: "{dv_root}/tools/fi_sim.tcl" + + // Coverage related. + cov_db_dir: "{scratch_path}/coverage/{build_mode}.vdb" + + // Individual test specific coverage data - this will be deleted if the test fails + // so that coverage from failiing tests is not included in the final report. + cov_db_test_dir_name: "{run_dir_name}.{svseed}" + cov_db_test_dir: "{cov_db_dir}/snps/coverage/db/testdata/{cov_db_test_dir_name}" + + // Merging coverage. + // "cov_db_dirs" is a special variable that appends all build directories in use. + // It is constructed by the tool itself. + cov_merge_dir: "{scratch_path}/cov_merge" + cov_merge_db_dir: "{cov_merge_dir}/merged.vdb" + cov_merge_cmd: "{job_prefix} urg" + cov_merge_opts: ["-lca", + "-full64", + // No need of generating report when merging coverage. + "-noreport", + // Parallel merge is slower than serial merge for most + // small blocks, and the corresponding flags are commented + // out. If this becomes problematic and you have a powerful + // machine available, uncomment the three flags below. + // Merge results from tests in parallel. + // "-parallel", + // "-parallel_split 20", + // "-parallel_temproot {cov_merge_dir}", + "+urg+lic+wait", + // Merge same assert instances found in different VDBs. + "-merge_across_libs", + // This enables grading on the merged vdb. + "-show tests", + // Enable union mode of flexible merging for covergroups. + "-flex_merge union", + // Use cov_db_dirs var for dir args; append -dir in front of each + "{eval_cmd} echo {cov_db_dirs} | sed -E 's/(\\S+)/-dir \\1/g'", + "-dbname {cov_merge_db_dir}"] + + // Generate coverage reports in text as well as html. + cov_report_dir: "{scratch_path}/cov_report" + cov_report_cmd: "{job_prefix} urg" + cov_report_opts: ["-lca", + "-full64", + "+urg+lic+wait", + // Lists all the tests that covered a given object. + "-show tests", + // Enable test grading using the "index" scheme, and the + // generation of the list of contributing tests with + // "testfile". + "-grade index testfile", + // Use simple ratio of total covered bins over total bins across cps & crs, + "-group ratio", + // Follow LRM naming conventions for array bins. + "-group lrm_bin_name", + // Compute overall coverage for per-instance covergroups individually rather + // than cumulatively. + "-group instcov_for_score", + "-dir {cov_merge_db_dir}", + "-line nocasedef", + "-format both", + // Prepend each el file with `-elfile`. + "{eval_cmd} echo {vcs_cov_excl_files} | sed -E 's/(\\S+)/-elfile \\1/g'", + "-report {cov_report_dir}"] + cov_report_txt: "{cov_report_dir}/dashboard.txt" + cov_report_page: "dashboard.html" + + // UNR related. + // All code coverage, assert isn't supported + cov_unr_metrics: "line+cond+fsm+tgl+branch" + cov_unr_dir: "{scratch_path}/cov_unr" + + cov_unr_common_build_opts: ["-sverilog -full64 -licqueue -ntb_opts uvm-1.2", + "-timescale={timescale}"] + + // Use recommended UUM (Unified usage model) 3 steps flow. The other flow defines macro + // "SYNTHESIS", which we have used in design + cov_unr_build_cmd: [// Step 1 + "{job_prefix} vlogan {cov_unr_common_build_opts} &&", + // Step 2 + "{job_prefix} vlogan {cov_unr_common_build_opts}", + // grep all defines from {build_opts} from step 2 + '''{eval_cmd} opts=`echo {build_opts}`; defines=; d=; \ + for o in $opts; \ + do \ + d=`echo $o | grep -o '+define+.*'`; \ + defines="$defines $d"; \ + done; \ + echo $defines + ''', + "-f {sv_flist} &&", + // Step 3 + "{job_prefix} vcs {cov_unr_common_build_opts}"] + cov_unr_build_opts: ["-cm {cov_unr_metrics}", + "{vcs_cov_cfg_file}", + "-unr={vcs_unr_cfg_file}", + "{dut}"] + + cov_unr_run_cmd: ["{job_prefix} ./unrSimv"] + cov_unr_run_opts: ["-unr"] + + // Analyzing coverage - this is done by invoking --cov-analyze switch. It opens up the + // GUI for visual analysis. + cov_analyze_dir: "{scratch_path}/cov_analyze" + cov_analyze_cmd: "{job_prefix} verdi" + cov_analyze_opts: ["-cov", + "-covdir {cov_merge_db_dir}", + "-line nocasedef" + "-elfile {vcs_cov_excl_files}"] + + // Vars that need to exported to the env. + exports: [ + { VCS_LICENSE_WAIT: 1 }, + { VCS_ARCH_OVERRIDE: "linux" }, + { FI_PROJ: "{fi_project}" }, + { FI_CAMPAIGN: "{fi_campaign}" }, + { FI_TC: "{fi_testcase}" }, + { SIMV: "{build_ex}" }, + { fi_sim_run_opts: "{run_opts_fi_sim}"} + ] + + // Defaults for VCS + // By default, collect all coverage metrics. + cov_metrics: "line+cond+fsm+tgl+branch+assert" + + // Supply the cov configuration file. + // Note that this needs to be set as `-cm_hier `. + // Include hierarchies for both code coverage and assertions. + vcs_cov_cfg_file: "" + + // Supply cov configuration file for -cm_fsmresetfilter. + vcs_fsm_reset_cov_cfg_file: "" + + // Supply the cov exclusion files. + vcs_cov_excl_files: [] + + // pass and fail patterns + build_fail_patterns: ["^Error-.*$"] + run_fail_patterns: ["^Error-.*$"] // Null pointer error + + build_modes: [ + { + name: z01x_gui + is_sim_mode: 1 + build_opts: ["-debug_access+all+reverse"] + run_opts: ["-gui", "-l {run_dir}/simv.log"] + } + { + name: z01x_gui_debug + // TODO as done for Xcelium see PR #24156 + is_sim_mode: 1 + build_opts: ["-debug_access+all+reverse"] + run_opts: ["-gui", "-l {run_dir}/simv.log"] + } + { + name: z01x_waves + is_sim_mode: 1 + build_opts: [// Enable generating Verdi Knowledge Database + "-kdb", + "-debug_access"] + } + { + name: z01x_waves_off + is_sim_mode: 1 + build_opts: [// disable dumping assertion failures to improve runtime performance + "-assert dbgopt"] + } + { + name: z01x_cov + is_sim_mode: 1 + build_opts: [// Enable the required cov metrics + "-cm {cov_metrics}", + // Set the coverage hierarchy + "{vcs_cov_cfg_file}", + "-cm_common_hier", + // Cover all continuous assignments + "-cm_line contassign", + // Dump toggle coverage on mdas, array of structs and on ports only + "-cm_tgl mda+structarr+portsonly", + // Report condition coverage within tasks, functions and for loops. + "-cm_cond for", + // Ignore initial blocks for coverage + "-cm_report noinitial", + // Filter unreachable/statically constant blocks. seqnoconst does a more + // sophisticated analysis including NBA / assignment with delays. + "-cm_seqnoconst", + // Creates a constfile.txt indicating a list of detected constants. + "-diag noconst" + // Don't count coverage that's coming from zero-time glitches + "-cm_glitch 0", + // Ignore warnings about not applying cm_glitch to path and FSM + "+warn=noVCM-OPTIGN", + // Coverage database output location + "-cm_dir {cov_db_dir}", + // The following option is to improve runtime performance + "-Xkeyopt=rtopt", + // Exclude FSM transitions that can only happen on reset + "-cm_fsmresetfilter {vcs_fsm_reset_cov_cfg_file}", + ] + + run_opts: [// Enable the required cov metrics + "-cm {cov_metrics}", + // Same directory as build + "-cm_dir {cov_db_dir}", + // Don't output cm.log which can be quite large + "-cm_log /dev/null", + // Provide a name to the coverage collected for this test + "-cm_name {cov_db_test_dir_name}"] + } + { + name: z01x_xprop + is_sim_mode: 1 + build_opts: ["-xprop={vcs_xprop_cfg_file}", + // Enable xmerge mode specific performance optimization + "-xprop=mmsopt"] + } + { + name: z01x_profile + is_sim_mode: 1 + build_opts: ["-simprofile"] + run_opts: ["-simprofile {profile}"] + } + { + name: z01x_loopdetect + is_sim_mode: 1 + build_opts: ["+vcs+loopreport", "+vcs+loopdetect"] + run_opts: ["+vcs+loopreport", "+vcs+loopdetect"] + } + ] +} diff --git a/hw/dv/tools/fi_sim.tcl b/hw/dv/tools/fi_sim.tcl new file mode 100644 index 0000000000000..0cf7e4253e5af --- /dev/null +++ b/hw/dv/tools/fi_sim.tcl @@ -0,0 +1,31 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +if {[info exists ::env(FI_CAMPAIGN)]} { + set fi_campaign "$::env(FI_CAMPAIGN)" +} else { + puts "ERROR: FI_CAMPAIGN environment variable not set!" + quit +} + +if {[info exists ::env(FI_TC)]} { + set fi_tc_name "$::env(FI_TC)" +} else { + puts "ERROR: FI_TC environment variable not set!" + quit +} + +create_testcases -name $fi_tc_name -exec "$::env(SIMV)" -args "$::env(run_opts) +ntb_random_seed=$::env(seed) +UVM_TEST_SEQ=$::env(uvm_test_seq) -assert disable_assert" -fsim_args " -fsim=limit+hyperactive+0 -fsim=fault+monitor+drop" + +# Currently hard coded to 2. +set_config -global_max_jobs 2 + +fsim + +report -campaign $fi_campaign -report $::env(run_dir)/fsim_result.rpt -overwrite -showfaultid + +puts "TEST PASSED CHECKS" + +fdb_disconnect +quit diff --git a/hw/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson b/hw/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson index 29a6550735c7a..840591b5ca9b3 100644 --- a/hw/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson +++ b/hw/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson @@ -18,5 +18,10 @@ name: xcelium_crypto_dpi_prince_build_opts build_opts: ["-I{build_dir}/fusesoc-work/src/{crypto_prince_ref_src_dir}"] } + + { + name: z01x_crypto_dpi_prince_build_opts + build_opts: ["-CFLAGS -I{build_dir}/fusesoc-work/src/{crypto_prince_ref_src_dir}"] + } ] } diff --git a/hw/ip_templates/flash_ctrl/dv/fi/block.sff b/hw/ip_templates/flash_ctrl/dv/fi/block.sff new file mode 100644 index 0000000000000..b32a61b3d3c7a --- /dev/null +++ b/hw/ip_templates/flash_ctrl/dv/fi/block.sff @@ -0,0 +1,7 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +FaultGenerate { + NA [0,1] {PORT "tb.dut.u_eflash.gen_flash_cores[0].**"} +} diff --git a/hw/ip_templates/flash_ctrl/dv/fi/strobe.sv b/hw/ip_templates/flash_ctrl/dv/fi/strobe.sv new file mode 100644 index 0000000000000..35e64d11dbf87 --- /dev/null +++ b/hw/ip_templates/flash_ctrl/dv/fi/strobe.sv @@ -0,0 +1,84 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module strobe; + + // Enable TL-UL integrity checker strobing points. + `define FI_SIM_Z01X + + initial begin + @(posedge tb.dut.rst_ni) + // Start FI injection job. For permanent faults, faults are injected + // at this point. For transient faults, the cycle counter starts from + // here. + $fs_inject; + end + + integer cmp; + + // Compare outputs of the golden and faulty machine. If we detect a mismatch, + // set the fault status to "observed, not detected" (ON). If the faulty machine + // produced an invalid value (X/Z), set to "potentially observed, not detected" + // (PN). + always@(negedge tb.dut.clk_i) begin + cmp = $fs_compare(tb.dut.mem_tl_o, tb.dut.prim_tl_o, tb.dut.core_tl_o); + if (1 == cmp) begin + // Mismatch beetween the golden and faulty machine. + $fs_set_status("ON", "tb.dut.mem_tl_o, tb.dut.prim_tl_o, tb.dut.core_tl_o"); + end else if (2 == cmp) begin + // Faulty machine has a X/Z at the output. + $fs_set_status("PN", "tb.dut.mem_tl_o, tb.dut.prim_tl_o, tb.dut.core_tl_o"); + end + end + + // In the previous always block, we have classified the fault as ON or PN. Now + // check, if one of the countermeasures has detected the fault. Then, set the + // fault status to "observed detected" (OD) or "potentially observed, detected" + // (PD). If one of the alert signal is invalid (X/Z), set to "observed, potentially + // detected" (OP), "potentially observed, potentially detected" (PP), or "not + // detected, potentially observed" (NP). + string status; + always@(negedge tb.dut.clk_i) begin + #2; + cmp = $fs_compare(tb.dut.alert_srcs, tb.dut.mem_tl_intg_err, tb.dut.prim_tl_intg_err, + tb.dut.core_tl_intg_err, tb.dut.flash_host_rderr); + status = $fs_get_status(); + if (1 == cmp) begin + if (status == "ON") begin + // Mismatch between golden and faulty machine and the alert was triggered. + $fs_drop_status("OD", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else if (status == "PN") begin + // Potential mismatch between golden and faulty machine and the alert was triggered. + $fs_drop_status("PD", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else begin + // No mismatch between golden and faulty machine but the alert was triggered. + $fs_set_status("ND", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end + end else if (2 == cmp) begin + if (status == "ON") begin + // Mismatch between golden and faulty machine and the alert was potentially triggered. + $fs_drop_status("OP", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else if (status == "PN") begin + // Potential mismatch between golden and faulty machine and the alert was potentially + // triggered. + $fs_drop_status("PP", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else begin + // No mismatch between golden and faulty machine but the alert was potentially triggered. + $fs_set_status("NP", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end + end + end +endmodule diff --git a/hw/ip_templates/flash_ctrl/dv/flash_ctrl_base_fi_sim_cfg.hjson.tpl b/hw/ip_templates/flash_ctrl/dv/flash_ctrl_base_fi_sim_cfg.hjson.tpl new file mode 100644 index 0000000000000..6d6af0b8b44df --- /dev/null +++ b/hw/ip_templates/flash_ctrl/dv/flash_ctrl_base_fi_sim_cfg.hjson.tpl @@ -0,0 +1,500 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + // Name of the sim cfg - typically same as the name of the DUT. + name: flash_ctrl + + // Top level dut name (sv module). + dut: flash_ctrl + + // Top level testbench name (sv module). + tb: tb + + // Fusesoc core file used for building the file list. + fusesoc_core: ${instance_vlnv("lowrisc:dv:flash_ctrl_fi_sim:0.1")} + + // Import additional common sim cfg files. + import_cfgs: [// Project wide common sim cfg file + "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson", + // Config files to get the correct flags for crypto_dpi_prince + "{proj_root}/hw/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson", + // Common CIP test lists + "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/mem_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/alert_test.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/intr_test.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/shadow_reg_errors_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/stress_all_test.hjson"], + + en_build_modes: ["{tool}_crypto_dpi_prince_build_opts"] + // Flash references pwrmgr directly, need to reference the top version + overrides: [ + { + name: "timescale" + value: "1ns/100ps" + } + ] + + // Add additional tops for simulation. + sim_tops: ["strobe"] + + // Default iterations for all tests - each test entry can override this. + reseed: 1 + + + run_modes: [ + { + name: csr_tests_mode + run_opts: ["+csr_test_mode=1"] + } + ] + + // Add default run opt + run_opts: ["+flash_rand_delay_en=1"] + + // Default UVM test and seq class name. + uvm_test: flash_ctrl_base_test + uvm_test_seq: flash_ctrl_base_vseq + + // Enable cdc instrumentation. + run_opts: ["+cdc_instrumentation_enabled=1"] + + // List of test specifications. + tests: [ + { + name: flash_ctrl_smoke + uvm_test_seq: flash_ctrl_smoke_vseq + reseed: 50 + } + { + name: flash_ctrl_smoke_hw + uvm_test_seq: flash_ctrl_smoke_hw_vseq + reseed: 5 + } + { + name: flash_ctrl_rand_ops + uvm_test_seq: flash_ctrl_rand_ops_vseq + reseed: 20 + } + { + name: flash_ctrl_sw_op + uvm_test_seq: flash_ctrl_sw_op_vseq + reseed: 5 + } + { + name: flash_ctrl_host_dir_rd + uvm_test_seq: flash_ctrl_host_dir_rd_vseq + run_opts: ["+zero_delays=1"] + reseed: 5 + } + { + name: flash_ctrl_rd_buff_evict + uvm_test_seq: flash_ctrl_rd_buff_evict_vseq + run_opts: ["+en_cov=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_arb + uvm_test_seq: flash_ctrl_phy_arb_vseq + run_opts: ["+zero_delays=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_sec_otp + uvm_test_seq: flash_ctrl_hw_sec_otp_vseq + run_opts: ["+test_timeout_ns=300_000_000_000"] + reseed: 50 + } + { + name: flash_ctrl_erase_suspend + uvm_test_seq: flash_ctrl_erase_suspend_vseq + run_opts: ["+zero_delays=1"] + reseed: 5 + } + { + name: flash_ctrl_hw_rma + uvm_test_seq: flash_ctrl_hw_rma_vseq + run_opts: ["+flash_program_latency=5", "+test_timeout_ns=300_000_000_000"] + reseed: 3 + } + { + name: flash_ctrl_hw_rma_reset + uvm_test_seq: flash_ctrl_hw_rma_reset_vseq + run_opts: ["+flash_program_latency=5", "+test_timeout_ns=300_000_000_000"] + reseed: 20 + } + { + name: flash_ctrl_otp_reset + uvm_test_seq: flash_ctrl_otp_reset_vseq + run_opts: ["+test_timeout_ns=300_000_000_000"] + reseed: 80 + } + { + name: flash_ctrl_host_ctrl_arb + uvm_test_seq: flash_ctrl_host_ctrl_arb_vseq + run_opts: ["+zero_delays=1", "+test_timeout_ns=300_000_000_000"] + reseed: 5 + } + { + name: flash_ctrl_mp_regions + uvm_test_seq: flash_ctrl_mp_regions_vseq + run_opts: ["+multi_alert=1", "+test_timeout_ns=300_000_000_000", + "+fast_rcvr_recov_err", "+op_readonly_on_info1_partition=0"] + reseed: 20 + } + { + name: flash_ctrl_fetch_code + uvm_test_seq: flash_ctrl_fetch_code_vseq + run_opts: ["+op_readonly_on_info_partition=1", + "+op_readonly_on_info1_partition=1"] + reseed: 10 + } + { + name: flash_ctrl_full_mem_access + uvm_test_seq: flash_ctrl_full_mem_access_vseq + run_opts: ["+test_timeout_ns=500_000_000_000"] + reseed: 5 + run_timeout_mins: 180 + } + { + name: flash_ctrl_error_prog_type + uvm_test_seq: flash_ctrl_error_prog_type_vseq + run_opts: ["+op_readonly_on_info_partition=1", + "+op_readonly_on_info1_partition=1"] + reseed: 5 + } + { + name: flash_ctrl_error_prog_win + uvm_test_seq: flash_ctrl_error_prog_win_vseq + reseed: 10 + } + { + name: flash_ctrl_error_mp + uvm_test_seq: flash_ctrl_error_mp_vseq + run_opts: ["+test_timeout_ns=300_000_000_000", "+op_readonly_on_info_partition=0", + "+op_readonly_on_info1_partition=0", "+op_readonly_on_info2_partition=0"] + reseed: 10 + } + { + name: flash_ctrl_invalid_op + uvm_test_seq: flash_ctrl_invalid_op_vseq + run_opts: ["+fast_rcvr_recov_err"] + reseed: 20 + } + { + name: flash_ctrl_mid_op_rst + uvm_test_seq: flash_ctrl_mid_op_rst_vseq + reseed: 5 + } + { + name: flash_ctrl_wo + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=100", "+otf_num_hr=0", "+otf_rd_pct=0", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_write_word_sweep + uvm_test_seq: flash_ctrl_write_word_sweep_vseq + run_opts: ["+scb_otf_en=1"] + reseed: 1 + } + { + name: flash_ctrl_read_word_sweep + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1"] + reseed: 1 + } + { + name: flash_ctrl_ro + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_rw + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+test_timeout_ns=5_000_000_000", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_read_word_sweep_serr + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3"] + reseed: 5 + } + { + name: flash_ctrl_ro_serr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0"] + reseed: 10 + } + { + name: flash_ctrl_rw_serr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000"] + reseed: 10 + } + { + name: flash_ctrl_serr_counter + uvm_test_seq: flash_ctrl_serr_counter_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=1", + "+otf_num_rw=50", "+otf_num_hr=5"] + reseed: 5 + } + { + name: flash_ctrl_serr_address + uvm_test_seq: flash_ctrl_serr_address_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=1", + "+otf_num_rw=5", "+otf_num_hr=0"] + reseed: 5 + } + { + name: flash_ctrl_read_word_sweep_derr + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_ro_derr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0", + "+bypass_alert_ready_to_end_check=1"] + reseed: 10 + } + { + name: flash_ctrl_rw_derr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", + "+bypass_alert_ready_to_end_check=1"] + reseed: 10 + } + { + name: flash_ctrl_derr_detect + uvm_test_seq: flash_ctrl_derr_detect_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=4", + "+otf_num_rw=50", "+otf_num_hr=200", + "+rerun=5", "+otf_wr_pct=1"] + reseed: 5 + } + { + name: flash_ctrl_oversize_error + uvm_test_seq: flash_ctrl_oversize_error_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=0", + "+otf_num_hr=1000", "+otf_num_rw=100", + "+otf_wr_pct=4", "+otf_rd_pct=4"] + reseed: 5 + } + { + name: flash_ctrl_integrity + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=4", "+ierr_pct=3", + "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_intr_rd + uvm_test_seq: flash_ctrl_intr_rd_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 40 + } + { + name: flash_ctrl_intr_wr + uvm_test_seq: flash_ctrl_intr_wr_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+test_timeout_ns=500_000_000"] + reseed: 10 + } + { + name: flash_ctrl_intr_rd_slow_flash + uvm_test_seq: flash_ctrl_intr_rd_vseq + run_opts: ["+scb_otf_en=1", "+flash_read_latency=50", "+flash_program_latency=500", "+test_timeout_ns=500_000_000"] + reseed: 40 + } + { + name: flash_ctrl_intr_wr_slow_flash + uvm_test_seq: flash_ctrl_intr_wr_vseq + run_opts: ["+scb_otf_en=1", "+flash_read_latency=50", "+flash_program_latency=500", + "+rd_buf_en_to=500_000", "+test_timeout_ns=1_000_000_000"] + reseed: 10 + } + { + name: flash_ctrl_prog_reset + uvm_test_seq: flash_ctrl_prog_reset_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+test_timeout_ns=500_000_000"] + reseed: 30 + } + { + name: flash_ctrl_rw_evict + uvm_test_seq: flash_ctrl_rw_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 40 + } + { + name: flash_ctrl_rw_evict_all_en + uvm_test_seq: flash_ctrl_rw_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1", + "+en_always_prog=1", "+en_rnd_data=0"] + reseed: 40 + } + { + name: flash_ctrl_re_evict + uvm_test_seq: flash_ctrl_re_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 20 + } + { + name: flash_ctrl_disable + uvm_test_seq: flash_ctrl_disable_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+en_always_all=1", + "+bypass_alert_ready_to_end_check=1"] + reseed: 50 + } + { + name: flash_ctrl_sec_cm + run_timeout_mins: 180 + } + { + name: flash_ctrl_sec_info_access + uvm_test_seq: flash_ctrl_info_part_access_vseq + reseed: 50 + } + { + name: flash_ctrl_stress_all + reseed: 5 + } + { + name: flash_ctrl_connect + uvm_test_seq: flash_ctrl_connect_vseq + reseed: 80 + } + { + name: flash_ctrl_rd_intg + uvm_test_seq: flash_ctrl_rd_path_intg_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+otf_num_hr=100", "+en_always_read=1"] + reseed: 3 + } + { + name: flash_ctrl_wr_intg + uvm_test_seq: flash_ctrl_wr_path_intg_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=10", "+otf_num_hr=0", "+ecc_mode=1", + "+en_always_prog=1", "+otf_rd_pct=0"] + reseed: 3 + } + { + name: flash_ctrl_access_after_disable + uvm_test_seq: flash_ctrl_access_after_disable_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+otf_num_rw=5", "+otf_num_hr=0", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 3 + } + { + name: flash_ctrl_fs_sup + uvm_test_seq: flash_ctrl_filesystem_support_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_all=1", "+en_all_info_acc=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_arb_redun + uvm_test_seq: flash_ctrl_phy_arb_redun_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=10", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_host_grant_err + uvm_test_seq: flash_ctrl_phy_host_grant_err_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=50", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_ack_consistency + uvm_test_seq: flash_ctrl_phy_ack_consistency_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=10", "+ecc_mode=1", "+bank0_pct=8", + "+otf_rd_pct=4", "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_config_regwen + uvm_test_seq: flash_ctrl_config_regwen_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_all=1"] + reseed: 5 + } + { + name: flash_ctrl_rma_err + uvm_test_seq: flash_ctrl_hw_rma_err_vseq + run_opts: ["+flash_program_latency=5", "+flash_erase_latency=50", "+test_timeout_ns=300_000_000_000"] + reseed: 3 + } + { + name: flash_ctrl_lcmgr_intg + uvm_test_seq: flash_ctrl_lcmgr_intg_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_read_seed_err + uvm_test_seq: flash_ctrl_hw_read_seed_err_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_prog_rma_wipe_err + uvm_test_seq: flash_ctrl_hw_prog_rma_wipe_err_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+flash_program_latency=5", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_rd_ooo + uvm_test_seq: flash_ctrl_rd_ooo_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=10", "+otf_num_hr=100", + "+ecc_mode=1"] + reseed: 1 + } + { + name: flash_ctrl_host_addr_infection + uvm_test_seq: flash_ctrl_host_addr_infection_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+otf_num_hr=100", "+en_always_read=1"] + reseed: 3 + } + { + name: flash_ctrl_basic_rw + uvm_test_seq: flash_ctrl_basic_rw_vseq + reseed: 3 + } + ] + + // List of regressions. + regressions: [ + { + name: smoke + tests: ["flash_ctrl_smoke"] + } + { + // For test clean up run subset of tests + name: evict + tests: ["flash_ctrl_rw_evict", + "flash_ctrl_re_evict", + "flash_ctrl_rw_evict_all_en" + ] + } + { + name: flash_err + tests: ["flash_ctrl_error_mp", "flash_ctrl_error_prog_win", + "flash_ctrl_error_prog_type" + ] + } + ] +} diff --git a/hw/ip_templates/flash_ctrl/dv/flash_ctrl_fi_sim.core.tpl b/hw/ip_templates/flash_ctrl/dv/flash_ctrl_fi_sim.core.tpl new file mode 100644 index 0000000000000..34dd6c0154dd3 --- /dev/null +++ b/hw/ip_templates/flash_ctrl/dv/flash_ctrl_fi_sim.core.tpl @@ -0,0 +1,47 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: ${instance_vlnv("lowrisc:dv:flash_ctrl_fi_sim:0.1")} +description: "FLASH_CTRL DV FI sim target" +filesets: + files_rtl: + depend: + - lowrisc:ip:tlul + - ${instance_vlnv("lowrisc:constants:top_pkg")} + - ${instance_vlnv("lowrisc:ip:flash_ctrl:0.1")} + file_type: systemVerilogSource + + files_dv: + depend: + - ${instance_vlnv("lowrisc:dv:flash_ctrl_bkdr_util")} + - ${instance_vlnv("lowrisc:dv:flash_ctrl_test")} + - ${instance_vlnv("lowrisc:dv:flash_ctrl_sva")} + - ${instance_vlnv("lowrisc:dv:flash_ctrl_cov")} + files: + - tb/tb.sv + file_type: systemVerilogSource + + files_fi_strobe: + files: + - fi/strobe.sv + file_type: systemVerilogSource + + files_fi_sff: + files: + - fi/block.sff + - fi/project.sff + file_type: standardFaultFormat + +targets: + default: &default_target + toplevel: tb + filesets: + - files_rtl + - files_dv + - files_fi_strobe + - files_fi_sff + + sim: + <<: *default_target + default_tool: vcs diff --git a/hw/ip_templates/flash_ctrl/dv/flash_ctrl_fi_sim_cfg.hjson b/hw/ip_templates/flash_ctrl/dv/flash_ctrl_fi_sim_cfg.hjson new file mode 100644 index 0000000000000..74cf0e8d098c6 --- /dev/null +++ b/hw/ip_templates/flash_ctrl/dv/flash_ctrl_fi_sim_cfg.hjson @@ -0,0 +1,25 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// We want to use a different tool in another flash_ctrl env, but overriding `tool` doesn't work, as +// it needs to first import all the included hjson to know what to override, but some fi_sim_cfg hjson +// files depends on the `tool` variable, such as {tool}.hjson. +// To solve this issue, split out the fi_sim_cfg file into 2 files. the base contains everything except +// `tool`, the other one includes the base and set the `tool`. +// +// In this file, only `tool` can be set. Tests or other configuration should be add in +// flash_ctrl_base_fi_sim_cfg.hjson. +{ + // FI Simulator used to sign off this block + tool: z01x + + import_cfgs: ["{self_dir}/flash_ctrl_base_fi_sim_cfg.hjson"] + + fi_core: "lowrisc:earlgrey_dv:flash_ctrl_fi_sim:0.1" + fi_src_dir: "{eval_cmd} echo \"{fi_core}\" | tr ':' '_'" + + block_sff_file: "{fi_src_dir}/fi/block.sff" + project_sff_file: "{fi_src_dir}/fi/project.sff" + strobe_file: "{fi_src_dir}/fi/strobe.sv" +} diff --git a/hw/ip_templates/flash_ctrl/rtl/flash_ctrl.sv.tpl b/hw/ip_templates/flash_ctrl/rtl/flash_ctrl.sv.tpl index a23f2a230c721..11b4b5438446e 100644 --- a/hw/ip_templates/flash_ctrl/rtl/flash_ctrl.sv.tpl +++ b/hw/ip_templates/flash_ctrl/rtl/flash_ctrl.sv.tpl @@ -1491,4 +1491,33 @@ module flash_ctrl // Alert assertions for reg_we onehot check `ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg_core, alert_tx_o[1]) + `ifdef FI_SIM_Z01X + // Check if there are any TL-UL integrity errors caused by faults that Z01X has introduced. + // Specific to fault injection simulation as Z01X expects that those strobing points are + // available in the design. + wire mem_tl_intg_err; + tlul_rsp_intg_chk #( + .EnableRspDataIntgCheck(1) + ) u_rsp_chk_mem ( + .tl_i (mem_tl_o), + .err_o(mem_tl_intg_err) + ); + + wire prim_tl_intg_err; + tlul_rsp_intg_chk #( + .EnableRspDataIntgCheck(1) + ) u_rsp_chk_prim ( + .tl_i (prim_tl_o), + .err_o(prim_tl_intg_err) + ); + + wire core_tl_intg_err; + tlul_rsp_intg_chk #( + .EnableRspDataIntgCheck(1) + ) u_rsp_chk_core ( + .tl_i (core_tl_o), + .err_o(core_tl_intg_err) + ); + `endif + endmodule diff --git a/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/fi/block.sff b/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/fi/block.sff new file mode 100644 index 0000000000000..b32a61b3d3c7a --- /dev/null +++ b/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/fi/block.sff @@ -0,0 +1,7 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +FaultGenerate { + NA [0,1] {PORT "tb.dut.u_eflash.gen_flash_cores[0].**"} +} diff --git a/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/fi/strobe.sv b/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/fi/strobe.sv new file mode 100644 index 0000000000000..35e64d11dbf87 --- /dev/null +++ b/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/fi/strobe.sv @@ -0,0 +1,84 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module strobe; + + // Enable TL-UL integrity checker strobing points. + `define FI_SIM_Z01X + + initial begin + @(posedge tb.dut.rst_ni) + // Start FI injection job. For permanent faults, faults are injected + // at this point. For transient faults, the cycle counter starts from + // here. + $fs_inject; + end + + integer cmp; + + // Compare outputs of the golden and faulty machine. If we detect a mismatch, + // set the fault status to "observed, not detected" (ON). If the faulty machine + // produced an invalid value (X/Z), set to "potentially observed, not detected" + // (PN). + always@(negedge tb.dut.clk_i) begin + cmp = $fs_compare(tb.dut.mem_tl_o, tb.dut.prim_tl_o, tb.dut.core_tl_o); + if (1 == cmp) begin + // Mismatch beetween the golden and faulty machine. + $fs_set_status("ON", "tb.dut.mem_tl_o, tb.dut.prim_tl_o, tb.dut.core_tl_o"); + end else if (2 == cmp) begin + // Faulty machine has a X/Z at the output. + $fs_set_status("PN", "tb.dut.mem_tl_o, tb.dut.prim_tl_o, tb.dut.core_tl_o"); + end + end + + // In the previous always block, we have classified the fault as ON or PN. Now + // check, if one of the countermeasures has detected the fault. Then, set the + // fault status to "observed detected" (OD) or "potentially observed, detected" + // (PD). If one of the alert signal is invalid (X/Z), set to "observed, potentially + // detected" (OP), "potentially observed, potentially detected" (PP), or "not + // detected, potentially observed" (NP). + string status; + always@(negedge tb.dut.clk_i) begin + #2; + cmp = $fs_compare(tb.dut.alert_srcs, tb.dut.mem_tl_intg_err, tb.dut.prim_tl_intg_err, + tb.dut.core_tl_intg_err, tb.dut.flash_host_rderr); + status = $fs_get_status(); + if (1 == cmp) begin + if (status == "ON") begin + // Mismatch between golden and faulty machine and the alert was triggered. + $fs_drop_status("OD", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else if (status == "PN") begin + // Potential mismatch between golden and faulty machine and the alert was triggered. + $fs_drop_status("PD", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else begin + // No mismatch between golden and faulty machine but the alert was triggered. + $fs_set_status("ND", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end + end else if (2 == cmp) begin + if (status == "ON") begin + // Mismatch between golden and faulty machine and the alert was potentially triggered. + $fs_drop_status("OP", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else if (status == "PN") begin + // Potential mismatch between golden and faulty machine and the alert was potentially + // triggered. + $fs_drop_status("PP", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else begin + // No mismatch between golden and faulty machine but the alert was potentially triggered. + $fs_set_status("NP", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end + end + end +endmodule diff --git a/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/flash_ctrl_base_fi_sim_cfg.hjson b/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/flash_ctrl_base_fi_sim_cfg.hjson new file mode 100644 index 0000000000000..1d4c3f7b7fbfa --- /dev/null +++ b/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/flash_ctrl_base_fi_sim_cfg.hjson @@ -0,0 +1,500 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + // Name of the sim cfg - typically same as the name of the DUT. + name: flash_ctrl + + // Top level dut name (sv module). + dut: flash_ctrl + + // Top level testbench name (sv module). + tb: tb + + // Fusesoc core file used for building the file list. + fusesoc_core: lowrisc:earlgrey_dv:flash_ctrl_fi_sim:0.1 + + // Import additional common sim cfg files. + import_cfgs: [// Project wide common sim cfg file + "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson", + // Config files to get the correct flags for crypto_dpi_prince + "{proj_root}/hw/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson", + // Common CIP test lists + "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/mem_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/alert_test.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/intr_test.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/shadow_reg_errors_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/stress_all_test.hjson"], + + en_build_modes: ["{tool}_crypto_dpi_prince_build_opts"] + // Flash references pwrmgr directly, need to reference the top version + overrides: [ + { + name: "timescale" + value: "1ns/100ps" + } + ] + + // Add additional tops for simulation. + sim_tops: ["strobe"] + + // Default iterations for all tests - each test entry can override this. + reseed: 1 + + + run_modes: [ + { + name: csr_tests_mode + run_opts: ["+csr_test_mode=1"] + } + ] + + // Add default run opt + run_opts: ["+flash_rand_delay_en=1"] + + // Default UVM test and seq class name. + uvm_test: flash_ctrl_base_test + uvm_test_seq: flash_ctrl_base_vseq + + // Enable cdc instrumentation. + run_opts: ["+cdc_instrumentation_enabled=1"] + + // List of test specifications. + tests: [ + { + name: flash_ctrl_smoke + uvm_test_seq: flash_ctrl_smoke_vseq + reseed: 50 + } + { + name: flash_ctrl_smoke_hw + uvm_test_seq: flash_ctrl_smoke_hw_vseq + reseed: 5 + } + { + name: flash_ctrl_rand_ops + uvm_test_seq: flash_ctrl_rand_ops_vseq + reseed: 20 + } + { + name: flash_ctrl_sw_op + uvm_test_seq: flash_ctrl_sw_op_vseq + reseed: 5 + } + { + name: flash_ctrl_host_dir_rd + uvm_test_seq: flash_ctrl_host_dir_rd_vseq + run_opts: ["+zero_delays=1"] + reseed: 5 + } + { + name: flash_ctrl_rd_buff_evict + uvm_test_seq: flash_ctrl_rd_buff_evict_vseq + run_opts: ["+en_cov=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_arb + uvm_test_seq: flash_ctrl_phy_arb_vseq + run_opts: ["+zero_delays=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_sec_otp + uvm_test_seq: flash_ctrl_hw_sec_otp_vseq + run_opts: ["+test_timeout_ns=300_000_000_000"] + reseed: 50 + } + { + name: flash_ctrl_erase_suspend + uvm_test_seq: flash_ctrl_erase_suspend_vseq + run_opts: ["+zero_delays=1"] + reseed: 5 + } + { + name: flash_ctrl_hw_rma + uvm_test_seq: flash_ctrl_hw_rma_vseq + run_opts: ["+flash_program_latency=5", "+test_timeout_ns=300_000_000_000"] + reseed: 3 + } + { + name: flash_ctrl_hw_rma_reset + uvm_test_seq: flash_ctrl_hw_rma_reset_vseq + run_opts: ["+flash_program_latency=5", "+test_timeout_ns=300_000_000_000"] + reseed: 20 + } + { + name: flash_ctrl_otp_reset + uvm_test_seq: flash_ctrl_otp_reset_vseq + run_opts: ["+test_timeout_ns=300_000_000_000"] + reseed: 80 + } + { + name: flash_ctrl_host_ctrl_arb + uvm_test_seq: flash_ctrl_host_ctrl_arb_vseq + run_opts: ["+zero_delays=1", "+test_timeout_ns=300_000_000_000"] + reseed: 5 + } + { + name: flash_ctrl_mp_regions + uvm_test_seq: flash_ctrl_mp_regions_vseq + run_opts: ["+multi_alert=1", "+test_timeout_ns=300_000_000_000", + "+fast_rcvr_recov_err", "+op_readonly_on_info1_partition=0"] + reseed: 20 + } + { + name: flash_ctrl_fetch_code + uvm_test_seq: flash_ctrl_fetch_code_vseq + run_opts: ["+op_readonly_on_info_partition=1", + "+op_readonly_on_info1_partition=1"] + reseed: 10 + } + { + name: flash_ctrl_full_mem_access + uvm_test_seq: flash_ctrl_full_mem_access_vseq + run_opts: ["+test_timeout_ns=500_000_000_000"] + reseed: 5 + run_timeout_mins: 180 + } + { + name: flash_ctrl_error_prog_type + uvm_test_seq: flash_ctrl_error_prog_type_vseq + run_opts: ["+op_readonly_on_info_partition=1", + "+op_readonly_on_info1_partition=1"] + reseed: 5 + } + { + name: flash_ctrl_error_prog_win + uvm_test_seq: flash_ctrl_error_prog_win_vseq + reseed: 10 + } + { + name: flash_ctrl_error_mp + uvm_test_seq: flash_ctrl_error_mp_vseq + run_opts: ["+test_timeout_ns=300_000_000_000", "+op_readonly_on_info_partition=0", + "+op_readonly_on_info1_partition=0", "+op_readonly_on_info2_partition=0"] + reseed: 10 + } + { + name: flash_ctrl_invalid_op + uvm_test_seq: flash_ctrl_invalid_op_vseq + run_opts: ["+fast_rcvr_recov_err"] + reseed: 20 + } + { + name: flash_ctrl_mid_op_rst + uvm_test_seq: flash_ctrl_mid_op_rst_vseq + reseed: 5 + } + { + name: flash_ctrl_wo + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=100", "+otf_num_hr=0", "+otf_rd_pct=0", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_write_word_sweep + uvm_test_seq: flash_ctrl_write_word_sweep_vseq + run_opts: ["+scb_otf_en=1"] + reseed: 1 + } + { + name: flash_ctrl_read_word_sweep + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1"] + reseed: 1 + } + { + name: flash_ctrl_ro + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_rw + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+test_timeout_ns=5_000_000_000", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_read_word_sweep_serr + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3"] + reseed: 5 + } + { + name: flash_ctrl_ro_serr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0"] + reseed: 10 + } + { + name: flash_ctrl_rw_serr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000"] + reseed: 10 + } + { + name: flash_ctrl_serr_counter + uvm_test_seq: flash_ctrl_serr_counter_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=1", + "+otf_num_rw=50", "+otf_num_hr=5"] + reseed: 5 + } + { + name: flash_ctrl_serr_address + uvm_test_seq: flash_ctrl_serr_address_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=1", + "+otf_num_rw=5", "+otf_num_hr=0"] + reseed: 5 + } + { + name: flash_ctrl_read_word_sweep_derr + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_ro_derr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0", + "+bypass_alert_ready_to_end_check=1"] + reseed: 10 + } + { + name: flash_ctrl_rw_derr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", + "+bypass_alert_ready_to_end_check=1"] + reseed: 10 + } + { + name: flash_ctrl_derr_detect + uvm_test_seq: flash_ctrl_derr_detect_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=4", + "+otf_num_rw=50", "+otf_num_hr=200", + "+rerun=5", "+otf_wr_pct=1"] + reseed: 5 + } + { + name: flash_ctrl_oversize_error + uvm_test_seq: flash_ctrl_oversize_error_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=0", + "+otf_num_hr=1000", "+otf_num_rw=100", + "+otf_wr_pct=4", "+otf_rd_pct=4"] + reseed: 5 + } + { + name: flash_ctrl_integrity + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=4", "+ierr_pct=3", + "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_intr_rd + uvm_test_seq: flash_ctrl_intr_rd_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 40 + } + { + name: flash_ctrl_intr_wr + uvm_test_seq: flash_ctrl_intr_wr_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+test_timeout_ns=500_000_000"] + reseed: 10 + } + { + name: flash_ctrl_intr_rd_slow_flash + uvm_test_seq: flash_ctrl_intr_rd_vseq + run_opts: ["+scb_otf_en=1", "+flash_read_latency=50", "+flash_program_latency=500", "+test_timeout_ns=500_000_000"] + reseed: 40 + } + { + name: flash_ctrl_intr_wr_slow_flash + uvm_test_seq: flash_ctrl_intr_wr_vseq + run_opts: ["+scb_otf_en=1", "+flash_read_latency=50", "+flash_program_latency=500", + "+rd_buf_en_to=500_000", "+test_timeout_ns=1_000_000_000"] + reseed: 10 + } + { + name: flash_ctrl_prog_reset + uvm_test_seq: flash_ctrl_prog_reset_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+test_timeout_ns=500_000_000"] + reseed: 30 + } + { + name: flash_ctrl_rw_evict + uvm_test_seq: flash_ctrl_rw_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 40 + } + { + name: flash_ctrl_rw_evict_all_en + uvm_test_seq: flash_ctrl_rw_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1", + "+en_always_prog=1", "+en_rnd_data=0"] + reseed: 40 + } + { + name: flash_ctrl_re_evict + uvm_test_seq: flash_ctrl_re_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 20 + } + { + name: flash_ctrl_disable + uvm_test_seq: flash_ctrl_disable_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+en_always_all=1", + "+bypass_alert_ready_to_end_check=1"] + reseed: 50 + } + { + name: flash_ctrl_sec_cm + run_timeout_mins: 180 + } + { + name: flash_ctrl_sec_info_access + uvm_test_seq: flash_ctrl_info_part_access_vseq + reseed: 50 + } + { + name: flash_ctrl_stress_all + reseed: 5 + } + { + name: flash_ctrl_connect + uvm_test_seq: flash_ctrl_connect_vseq + reseed: 80 + } + { + name: flash_ctrl_rd_intg + uvm_test_seq: flash_ctrl_rd_path_intg_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+otf_num_hr=100", "+en_always_read=1"] + reseed: 3 + } + { + name: flash_ctrl_wr_intg + uvm_test_seq: flash_ctrl_wr_path_intg_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=10", "+otf_num_hr=0", "+ecc_mode=1", + "+en_always_prog=1", "+otf_rd_pct=0"] + reseed: 3 + } + { + name: flash_ctrl_access_after_disable + uvm_test_seq: flash_ctrl_access_after_disable_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+otf_num_rw=5", "+otf_num_hr=0", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 3 + } + { + name: flash_ctrl_fs_sup + uvm_test_seq: flash_ctrl_filesystem_support_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_all=1", "+en_all_info_acc=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_arb_redun + uvm_test_seq: flash_ctrl_phy_arb_redun_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=10", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_host_grant_err + uvm_test_seq: flash_ctrl_phy_host_grant_err_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=50", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_ack_consistency + uvm_test_seq: flash_ctrl_phy_ack_consistency_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=10", "+ecc_mode=1", "+bank0_pct=8", + "+otf_rd_pct=4", "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_config_regwen + uvm_test_seq: flash_ctrl_config_regwen_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_all=1"] + reseed: 5 + } + { + name: flash_ctrl_rma_err + uvm_test_seq: flash_ctrl_hw_rma_err_vseq + run_opts: ["+flash_program_latency=5", "+flash_erase_latency=50", "+test_timeout_ns=300_000_000_000"] + reseed: 3 + } + { + name: flash_ctrl_lcmgr_intg + uvm_test_seq: flash_ctrl_lcmgr_intg_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_read_seed_err + uvm_test_seq: flash_ctrl_hw_read_seed_err_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_prog_rma_wipe_err + uvm_test_seq: flash_ctrl_hw_prog_rma_wipe_err_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+flash_program_latency=5", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_rd_ooo + uvm_test_seq: flash_ctrl_rd_ooo_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=10", "+otf_num_hr=100", + "+ecc_mode=1"] + reseed: 1 + } + { + name: flash_ctrl_host_addr_infection + uvm_test_seq: flash_ctrl_host_addr_infection_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+otf_num_hr=100", "+en_always_read=1"] + reseed: 3 + } + { + name: flash_ctrl_basic_rw + uvm_test_seq: flash_ctrl_basic_rw_vseq + reseed: 3 + } + ] + + // List of regressions. + regressions: [ + { + name: smoke + tests: ["flash_ctrl_smoke"] + } + { + // For test clean up run subset of tests + name: evict + tests: ["flash_ctrl_rw_evict", + "flash_ctrl_re_evict", + "flash_ctrl_rw_evict_all_en" + ] + } + { + name: flash_err + tests: ["flash_ctrl_error_mp", "flash_ctrl_error_prog_win", + "flash_ctrl_error_prog_type" + ] + } + ] +} diff --git a/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim.core b/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim.core new file mode 100644 index 0000000000000..4648f75eb3ca5 --- /dev/null +++ b/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim.core @@ -0,0 +1,47 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:earlgrey_dv:flash_ctrl_fi_sim:0.1 +description: "FLASH_CTRL DV FI sim target" +filesets: + files_rtl: + depend: + - lowrisc:ip:tlul + - lowrisc:earlgrey_constants:top_pkg + - lowrisc:earlgrey_ip:flash_ctrl:0.1 + file_type: systemVerilogSource + + files_dv: + depend: + - lowrisc:earlgrey_dv:flash_ctrl_bkdr_util + - lowrisc:earlgrey_dv:flash_ctrl_test + - lowrisc:earlgrey_dv:flash_ctrl_sva + - lowrisc:earlgrey_dv:flash_ctrl_cov + files: + - tb/tb.sv + file_type: systemVerilogSource + + files_fi_strobe: + files: + - fi/strobe.sv + file_type: systemVerilogSource + + files_fi_sff: + files: + - fi/block.sff + - fi/project.sff + file_type: standardFaultFormat + +targets: + default: &default_target + toplevel: tb + filesets: + - files_rtl + - files_dv + - files_fi_strobe + - files_fi_sff + + sim: + <<: *default_target + default_tool: vcs diff --git a/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim_cfg.hjson b/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim_cfg.hjson new file mode 100644 index 0000000000000..74cf0e8d098c6 --- /dev/null +++ b/hw/top_earlgrey/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim_cfg.hjson @@ -0,0 +1,25 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// We want to use a different tool in another flash_ctrl env, but overriding `tool` doesn't work, as +// it needs to first import all the included hjson to know what to override, but some fi_sim_cfg hjson +// files depends on the `tool` variable, such as {tool}.hjson. +// To solve this issue, split out the fi_sim_cfg file into 2 files. the base contains everything except +// `tool`, the other one includes the base and set the `tool`. +// +// In this file, only `tool` can be set. Tests or other configuration should be add in +// flash_ctrl_base_fi_sim_cfg.hjson. +{ + // FI Simulator used to sign off this block + tool: z01x + + import_cfgs: ["{self_dir}/flash_ctrl_base_fi_sim_cfg.hjson"] + + fi_core: "lowrisc:earlgrey_dv:flash_ctrl_fi_sim:0.1" + fi_src_dir: "{eval_cmd} echo \"{fi_core}\" | tr ':' '_'" + + block_sff_file: "{fi_src_dir}/fi/block.sff" + project_sff_file: "{fi_src_dir}/fi/project.sff" + strobe_file: "{fi_src_dir}/fi/strobe.sv" +} diff --git a/hw/top_earlgrey/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv b/hw/top_earlgrey/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv index 32263ee71acb9..d6396d5b4ea60 100644 --- a/hw/top_earlgrey/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv +++ b/hw/top_earlgrey/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv @@ -1492,4 +1492,33 @@ module flash_ctrl // Alert assertions for reg_we onehot check `ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg_core, alert_tx_o[1]) + `ifdef FI_SIM_Z01X + // Check if there are any TL-UL integrity errors caused by faults that Z01X has introduced. + // Specific to fault injection simulation as Z01X expects that those strobing points are + // available in the design. + wire mem_tl_intg_err; + tlul_rsp_intg_chk #( + .EnableRspDataIntgCheck(1) + ) u_rsp_chk_mem ( + .tl_i (mem_tl_o), + .err_o(mem_tl_intg_err) + ); + + wire prim_tl_intg_err; + tlul_rsp_intg_chk #( + .EnableRspDataIntgCheck(1) + ) u_rsp_chk_prim ( + .tl_i (prim_tl_o), + .err_o(prim_tl_intg_err) + ); + + wire core_tl_intg_err; + tlul_rsp_intg_chk #( + .EnableRspDataIntgCheck(1) + ) u_rsp_chk_core ( + .tl_i (core_tl_o), + .err_o(core_tl_intg_err) + ); + `endif + endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/fi/block.sff b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/fi/block.sff new file mode 100644 index 0000000000000..b32a61b3d3c7a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/fi/block.sff @@ -0,0 +1,7 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +FaultGenerate { + NA [0,1] {PORT "tb.dut.u_eflash.gen_flash_cores[0].**"} +} diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/fi/strobe.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/fi/strobe.sv new file mode 100644 index 0000000000000..35e64d11dbf87 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/fi/strobe.sv @@ -0,0 +1,84 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module strobe; + + // Enable TL-UL integrity checker strobing points. + `define FI_SIM_Z01X + + initial begin + @(posedge tb.dut.rst_ni) + // Start FI injection job. For permanent faults, faults are injected + // at this point. For transient faults, the cycle counter starts from + // here. + $fs_inject; + end + + integer cmp; + + // Compare outputs of the golden and faulty machine. If we detect a mismatch, + // set the fault status to "observed, not detected" (ON). If the faulty machine + // produced an invalid value (X/Z), set to "potentially observed, not detected" + // (PN). + always@(negedge tb.dut.clk_i) begin + cmp = $fs_compare(tb.dut.mem_tl_o, tb.dut.prim_tl_o, tb.dut.core_tl_o); + if (1 == cmp) begin + // Mismatch beetween the golden and faulty machine. + $fs_set_status("ON", "tb.dut.mem_tl_o, tb.dut.prim_tl_o, tb.dut.core_tl_o"); + end else if (2 == cmp) begin + // Faulty machine has a X/Z at the output. + $fs_set_status("PN", "tb.dut.mem_tl_o, tb.dut.prim_tl_o, tb.dut.core_tl_o"); + end + end + + // In the previous always block, we have classified the fault as ON or PN. Now + // check, if one of the countermeasures has detected the fault. Then, set the + // fault status to "observed detected" (OD) or "potentially observed, detected" + // (PD). If one of the alert signal is invalid (X/Z), set to "observed, potentially + // detected" (OP), "potentially observed, potentially detected" (PP), or "not + // detected, potentially observed" (NP). + string status; + always@(negedge tb.dut.clk_i) begin + #2; + cmp = $fs_compare(tb.dut.alert_srcs, tb.dut.mem_tl_intg_err, tb.dut.prim_tl_intg_err, + tb.dut.core_tl_intg_err, tb.dut.flash_host_rderr); + status = $fs_get_status(); + if (1 == cmp) begin + if (status == "ON") begin + // Mismatch between golden and faulty machine and the alert was triggered. + $fs_drop_status("OD", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else if (status == "PN") begin + // Potential mismatch between golden and faulty machine and the alert was triggered. + $fs_drop_status("PD", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else begin + // No mismatch between golden and faulty machine but the alert was triggered. + $fs_set_status("ND", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end + end else if (2 == cmp) begin + if (status == "ON") begin + // Mismatch between golden and faulty machine and the alert was potentially triggered. + $fs_drop_status("OP", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else if (status == "PN") begin + // Potential mismatch between golden and faulty machine and the alert was potentially + // triggered. + $fs_drop_status("PP", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end else begin + // No mismatch between golden and faulty machine but the alert was potentially triggered. + $fs_set_status("NP", {"tb.dut.alert_srcs, tb.dut.mem_tl_intg_err,", + "tb.dut.prim_tl_intg_err, tb.dut.core_tl_intg_err,", + "tb.dut.flash_host_rderr"}); + end + end + end +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_base_fi_sim_cfg.hjson b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_base_fi_sim_cfg.hjson new file mode 100644 index 0000000000000..32f672bcc72ba --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_base_fi_sim_cfg.hjson @@ -0,0 +1,500 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + // Name of the sim cfg - typically same as the name of the DUT. + name: flash_ctrl + + // Top level dut name (sv module). + dut: flash_ctrl + + // Top level testbench name (sv module). + tb: tb + + // Fusesoc core file used for building the file list. + fusesoc_core: lowrisc:englishbreakfast_dv:flash_ctrl_fi_sim:0.1 + + // Import additional common sim cfg files. + import_cfgs: [// Project wide common sim cfg file + "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson", + // Config files to get the correct flags for crypto_dpi_prince + "{proj_root}/hw/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson", + // Common CIP test lists + "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/mem_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/alert_test.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/intr_test.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/shadow_reg_errors_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/stress_all_test.hjson"], + + en_build_modes: ["{tool}_crypto_dpi_prince_build_opts"] + // Flash references pwrmgr directly, need to reference the top version + overrides: [ + { + name: "timescale" + value: "1ns/100ps" + } + ] + + // Add additional tops for simulation. + sim_tops: ["strobe"] + + // Default iterations for all tests - each test entry can override this. + reseed: 1 + + + run_modes: [ + { + name: csr_tests_mode + run_opts: ["+csr_test_mode=1"] + } + ] + + // Add default run opt + run_opts: ["+flash_rand_delay_en=1"] + + // Default UVM test and seq class name. + uvm_test: flash_ctrl_base_test + uvm_test_seq: flash_ctrl_base_vseq + + // Enable cdc instrumentation. + run_opts: ["+cdc_instrumentation_enabled=1"] + + // List of test specifications. + tests: [ + { + name: flash_ctrl_smoke + uvm_test_seq: flash_ctrl_smoke_vseq + reseed: 50 + } + { + name: flash_ctrl_smoke_hw + uvm_test_seq: flash_ctrl_smoke_hw_vseq + reseed: 5 + } + { + name: flash_ctrl_rand_ops + uvm_test_seq: flash_ctrl_rand_ops_vseq + reseed: 20 + } + { + name: flash_ctrl_sw_op + uvm_test_seq: flash_ctrl_sw_op_vseq + reseed: 5 + } + { + name: flash_ctrl_host_dir_rd + uvm_test_seq: flash_ctrl_host_dir_rd_vseq + run_opts: ["+zero_delays=1"] + reseed: 5 + } + { + name: flash_ctrl_rd_buff_evict + uvm_test_seq: flash_ctrl_rd_buff_evict_vseq + run_opts: ["+en_cov=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_arb + uvm_test_seq: flash_ctrl_phy_arb_vseq + run_opts: ["+zero_delays=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_sec_otp + uvm_test_seq: flash_ctrl_hw_sec_otp_vseq + run_opts: ["+test_timeout_ns=300_000_000_000"] + reseed: 50 + } + { + name: flash_ctrl_erase_suspend + uvm_test_seq: flash_ctrl_erase_suspend_vseq + run_opts: ["+zero_delays=1"] + reseed: 5 + } + { + name: flash_ctrl_hw_rma + uvm_test_seq: flash_ctrl_hw_rma_vseq + run_opts: ["+flash_program_latency=5", "+test_timeout_ns=300_000_000_000"] + reseed: 3 + } + { + name: flash_ctrl_hw_rma_reset + uvm_test_seq: flash_ctrl_hw_rma_reset_vseq + run_opts: ["+flash_program_latency=5", "+test_timeout_ns=300_000_000_000"] + reseed: 20 + } + { + name: flash_ctrl_otp_reset + uvm_test_seq: flash_ctrl_otp_reset_vseq + run_opts: ["+test_timeout_ns=300_000_000_000"] + reseed: 80 + } + { + name: flash_ctrl_host_ctrl_arb + uvm_test_seq: flash_ctrl_host_ctrl_arb_vseq + run_opts: ["+zero_delays=1", "+test_timeout_ns=300_000_000_000"] + reseed: 5 + } + { + name: flash_ctrl_mp_regions + uvm_test_seq: flash_ctrl_mp_regions_vseq + run_opts: ["+multi_alert=1", "+test_timeout_ns=300_000_000_000", + "+fast_rcvr_recov_err", "+op_readonly_on_info1_partition=0"] + reseed: 20 + } + { + name: flash_ctrl_fetch_code + uvm_test_seq: flash_ctrl_fetch_code_vseq + run_opts: ["+op_readonly_on_info_partition=1", + "+op_readonly_on_info1_partition=1"] + reseed: 10 + } + { + name: flash_ctrl_full_mem_access + uvm_test_seq: flash_ctrl_full_mem_access_vseq + run_opts: ["+test_timeout_ns=500_000_000_000"] + reseed: 5 + run_timeout_mins: 180 + } + { + name: flash_ctrl_error_prog_type + uvm_test_seq: flash_ctrl_error_prog_type_vseq + run_opts: ["+op_readonly_on_info_partition=1", + "+op_readonly_on_info1_partition=1"] + reseed: 5 + } + { + name: flash_ctrl_error_prog_win + uvm_test_seq: flash_ctrl_error_prog_win_vseq + reseed: 10 + } + { + name: flash_ctrl_error_mp + uvm_test_seq: flash_ctrl_error_mp_vseq + run_opts: ["+test_timeout_ns=300_000_000_000", "+op_readonly_on_info_partition=0", + "+op_readonly_on_info1_partition=0", "+op_readonly_on_info2_partition=0"] + reseed: 10 + } + { + name: flash_ctrl_invalid_op + uvm_test_seq: flash_ctrl_invalid_op_vseq + run_opts: ["+fast_rcvr_recov_err"] + reseed: 20 + } + { + name: flash_ctrl_mid_op_rst + uvm_test_seq: flash_ctrl_mid_op_rst_vseq + reseed: 5 + } + { + name: flash_ctrl_wo + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=100", "+otf_num_hr=0", "+otf_rd_pct=0", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_write_word_sweep + uvm_test_seq: flash_ctrl_write_word_sweep_vseq + run_opts: ["+scb_otf_en=1"] + reseed: 1 + } + { + name: flash_ctrl_read_word_sweep + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1"] + reseed: 1 + } + { + name: flash_ctrl_ro + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_rw + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+test_timeout_ns=5_000_000_000", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_read_word_sweep_serr + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3"] + reseed: 5 + } + { + name: flash_ctrl_ro_serr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0"] + reseed: 10 + } + { + name: flash_ctrl_rw_serr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000"] + reseed: 10 + } + { + name: flash_ctrl_serr_counter + uvm_test_seq: flash_ctrl_serr_counter_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=1", + "+otf_num_rw=50", "+otf_num_hr=5"] + reseed: 5 + } + { + name: flash_ctrl_serr_address + uvm_test_seq: flash_ctrl_serr_address_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=1", + "+otf_num_rw=5", "+otf_num_hr=0"] + reseed: 5 + } + { + name: flash_ctrl_read_word_sweep_derr + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_ro_derr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0", + "+bypass_alert_ready_to_end_check=1"] + reseed: 10 + } + { + name: flash_ctrl_rw_derr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", + "+bypass_alert_ready_to_end_check=1"] + reseed: 10 + } + { + name: flash_ctrl_derr_detect + uvm_test_seq: flash_ctrl_derr_detect_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=4", + "+otf_num_rw=50", "+otf_num_hr=200", + "+rerun=5", "+otf_wr_pct=1"] + reseed: 5 + } + { + name: flash_ctrl_oversize_error + uvm_test_seq: flash_ctrl_oversize_error_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=0", + "+otf_num_hr=1000", "+otf_num_rw=100", + "+otf_wr_pct=4", "+otf_rd_pct=4"] + reseed: 5 + } + { + name: flash_ctrl_integrity + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=4", "+ierr_pct=3", + "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_intr_rd + uvm_test_seq: flash_ctrl_intr_rd_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 40 + } + { + name: flash_ctrl_intr_wr + uvm_test_seq: flash_ctrl_intr_wr_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+test_timeout_ns=500_000_000"] + reseed: 10 + } + { + name: flash_ctrl_intr_rd_slow_flash + uvm_test_seq: flash_ctrl_intr_rd_vseq + run_opts: ["+scb_otf_en=1", "+flash_read_latency=50", "+flash_program_latency=500", "+test_timeout_ns=500_000_000"] + reseed: 40 + } + { + name: flash_ctrl_intr_wr_slow_flash + uvm_test_seq: flash_ctrl_intr_wr_vseq + run_opts: ["+scb_otf_en=1", "+flash_read_latency=50", "+flash_program_latency=500", + "+rd_buf_en_to=500_000", "+test_timeout_ns=1_000_000_000"] + reseed: 10 + } + { + name: flash_ctrl_prog_reset + uvm_test_seq: flash_ctrl_prog_reset_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+test_timeout_ns=500_000_000"] + reseed: 30 + } + { + name: flash_ctrl_rw_evict + uvm_test_seq: flash_ctrl_rw_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 40 + } + { + name: flash_ctrl_rw_evict_all_en + uvm_test_seq: flash_ctrl_rw_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1", + "+en_always_prog=1", "+en_rnd_data=0"] + reseed: 40 + } + { + name: flash_ctrl_re_evict + uvm_test_seq: flash_ctrl_re_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 20 + } + { + name: flash_ctrl_disable + uvm_test_seq: flash_ctrl_disable_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+en_always_all=1", + "+bypass_alert_ready_to_end_check=1"] + reseed: 50 + } + { + name: flash_ctrl_sec_cm + run_timeout_mins: 180 + } + { + name: flash_ctrl_sec_info_access + uvm_test_seq: flash_ctrl_info_part_access_vseq + reseed: 50 + } + { + name: flash_ctrl_stress_all + reseed: 5 + } + { + name: flash_ctrl_connect + uvm_test_seq: flash_ctrl_connect_vseq + reseed: 80 + } + { + name: flash_ctrl_rd_intg + uvm_test_seq: flash_ctrl_rd_path_intg_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+otf_num_hr=100", "+en_always_read=1"] + reseed: 3 + } + { + name: flash_ctrl_wr_intg + uvm_test_seq: flash_ctrl_wr_path_intg_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=10", "+otf_num_hr=0", "+ecc_mode=1", + "+en_always_prog=1", "+otf_rd_pct=0"] + reseed: 3 + } + { + name: flash_ctrl_access_after_disable + uvm_test_seq: flash_ctrl_access_after_disable_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+otf_num_rw=5", "+otf_num_hr=0", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 3 + } + { + name: flash_ctrl_fs_sup + uvm_test_seq: flash_ctrl_filesystem_support_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_all=1", "+en_all_info_acc=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_arb_redun + uvm_test_seq: flash_ctrl_phy_arb_redun_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=10", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_host_grant_err + uvm_test_seq: flash_ctrl_phy_host_grant_err_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=50", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_ack_consistency + uvm_test_seq: flash_ctrl_phy_ack_consistency_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=10", "+ecc_mode=1", "+bank0_pct=8", + "+otf_rd_pct=4", "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_config_regwen + uvm_test_seq: flash_ctrl_config_regwen_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_all=1"] + reseed: 5 + } + { + name: flash_ctrl_rma_err + uvm_test_seq: flash_ctrl_hw_rma_err_vseq + run_opts: ["+flash_program_latency=5", "+flash_erase_latency=50", "+test_timeout_ns=300_000_000_000"] + reseed: 3 + } + { + name: flash_ctrl_lcmgr_intg + uvm_test_seq: flash_ctrl_lcmgr_intg_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_read_seed_err + uvm_test_seq: flash_ctrl_hw_read_seed_err_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_prog_rma_wipe_err + uvm_test_seq: flash_ctrl_hw_prog_rma_wipe_err_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+flash_program_latency=5", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_rd_ooo + uvm_test_seq: flash_ctrl_rd_ooo_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=10", "+otf_num_hr=100", + "+ecc_mode=1"] + reseed: 1 + } + { + name: flash_ctrl_host_addr_infection + uvm_test_seq: flash_ctrl_host_addr_infection_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+otf_num_hr=100", "+en_always_read=1"] + reseed: 3 + } + { + name: flash_ctrl_basic_rw + uvm_test_seq: flash_ctrl_basic_rw_vseq + reseed: 3 + } + ] + + // List of regressions. + regressions: [ + { + name: smoke + tests: ["flash_ctrl_smoke"] + } + { + // For test clean up run subset of tests + name: evict + tests: ["flash_ctrl_rw_evict", + "flash_ctrl_re_evict", + "flash_ctrl_rw_evict_all_en" + ] + } + { + name: flash_err + tests: ["flash_ctrl_error_mp", "flash_ctrl_error_prog_win", + "flash_ctrl_error_prog_type" + ] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim.core b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim.core new file mode 100644 index 0000000000000..07121b7eae146 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim.core @@ -0,0 +1,47 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:englishbreakfast_dv:flash_ctrl_fi_sim:0.1 +description: "FLASH_CTRL DV FI sim target" +filesets: + files_rtl: + depend: + - lowrisc:ip:tlul + - lowrisc:englishbreakfast_constants:top_pkg + - lowrisc:englishbreakfast_ip:flash_ctrl:0.1 + file_type: systemVerilogSource + + files_dv: + depend: + - lowrisc:englishbreakfast_dv:flash_ctrl_bkdr_util + - lowrisc:englishbreakfast_dv:flash_ctrl_test + - lowrisc:englishbreakfast_dv:flash_ctrl_sva + - lowrisc:englishbreakfast_dv:flash_ctrl_cov + files: + - tb/tb.sv + file_type: systemVerilogSource + + files_fi_strobe: + files: + - fi/strobe.sv + file_type: systemVerilogSource + + files_fi_sff: + files: + - fi/block.sff + - fi/project.sff + file_type: standardFaultFormat + +targets: + default: &default_target + toplevel: tb + filesets: + - files_rtl + - files_dv + - files_fi_strobe + - files_fi_sff + + sim: + <<: *default_target + default_tool: vcs diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim_cfg.hjson b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim_cfg.hjson new file mode 100644 index 0000000000000..74cf0e8d098c6 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_fi_sim_cfg.hjson @@ -0,0 +1,25 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// We want to use a different tool in another flash_ctrl env, but overriding `tool` doesn't work, as +// it needs to first import all the included hjson to know what to override, but some fi_sim_cfg hjson +// files depends on the `tool` variable, such as {tool}.hjson. +// To solve this issue, split out the fi_sim_cfg file into 2 files. the base contains everything except +// `tool`, the other one includes the base and set the `tool`. +// +// In this file, only `tool` can be set. Tests or other configuration should be add in +// flash_ctrl_base_fi_sim_cfg.hjson. +{ + // FI Simulator used to sign off this block + tool: z01x + + import_cfgs: ["{self_dir}/flash_ctrl_base_fi_sim_cfg.hjson"] + + fi_core: "lowrisc:earlgrey_dv:flash_ctrl_fi_sim:0.1" + fi_src_dir: "{eval_cmd} echo \"{fi_core}\" | tr ':' '_'" + + block_sff_file: "{fi_src_dir}/fi/block.sff" + project_sff_file: "{fi_src_dir}/fi/project.sff" + strobe_file: "{fi_src_dir}/fi/strobe.sv" +} diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv index 32263ee71acb9..d6396d5b4ea60 100644 --- a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv @@ -1492,4 +1492,33 @@ module flash_ctrl // Alert assertions for reg_we onehot check `ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg_core, alert_tx_o[1]) + `ifdef FI_SIM_Z01X + // Check if there are any TL-UL integrity errors caused by faults that Z01X has introduced. + // Specific to fault injection simulation as Z01X expects that those strobing points are + // available in the design. + wire mem_tl_intg_err; + tlul_rsp_intg_chk #( + .EnableRspDataIntgCheck(1) + ) u_rsp_chk_mem ( + .tl_i (mem_tl_o), + .err_o(mem_tl_intg_err) + ); + + wire prim_tl_intg_err; + tlul_rsp_intg_chk #( + .EnableRspDataIntgCheck(1) + ) u_rsp_chk_prim ( + .tl_i (prim_tl_o), + .err_o(prim_tl_intg_err) + ); + + wire core_tl_intg_err; + tlul_rsp_intg_chk #( + .EnableRspDataIntgCheck(1) + ) u_rsp_chk_core ( + .tl_i (core_tl_o), + .err_o(core_tl_intg_err) + ); + `endif + endmodule diff --git a/util/dvsim/Deploy.py b/util/dvsim/Deploy.py index 126f28cd6b34a..284345731c030 100644 --- a/util/dvsim/Deploy.py +++ b/util/dvsim/Deploy.py @@ -351,6 +351,7 @@ def _define_attrs(self): "build_dir": False, "build_opts": False, "post_build_cmds": False, + "post_build_opts": False, }) self.mandatory_misc_attrs.update({ @@ -422,6 +423,7 @@ def _define_attrs(self): "build_log": False, "build_timeout_mins": False, "post_build_cmds": False, + "post_build_opts": False, "pre_build_cmds": False, # Report processing diff --git a/util/dvsim/Regression.py b/util/dvsim/Regression.py index 3882702252635..cc270fe9f3cc1 100644 --- a/util/dvsim/Regression.py +++ b/util/dvsim/Regression.py @@ -40,6 +40,7 @@ def __init__(self, regdict): self.pre_run_cmds = [] self.post_run_cmds = [] self.build_opts = [] + self.post_build_opts = [] self.run_opts = [] super().__init__("regression", regdict) @@ -116,6 +117,7 @@ def create_regressions(regdicts, sim_cfg, tests): regression_obj.build_opts.extend(sim_mode_obj.build_opts) regression_obj.pre_run_cmds.extend(sim_mode_obj.pre_run_cmds) regression_obj.post_run_cmds.extend(sim_mode_obj.post_run_cmds) + regression_obj.post_build_opts.extend(sim_mode_obj.post_build_opts) regression_obj.run_opts.extend(sim_mode_obj.run_opts) # Unpack the run_modes @@ -167,6 +169,7 @@ def merge_regression_opts(self): test.build_mode.pre_build_cmds.extend(self.pre_build_cmds) test.build_mode.post_build_cmds.extend(self.post_build_cmds) test.build_mode.build_opts.extend(self.build_opts) + test.build_mode.post_build_opts.extend(self.post_build_opts) processed_build_modes.append(test.build_mode.name) test.pre_run_cmds.extend(self.pre_run_cmds) test.post_run_cmds.extend(self.post_run_cmds) diff --git a/util/dvsim/SimCfg.py b/util/dvsim/SimCfg.py index 5891168a0ea89..07d80f7011148 100644 --- a/util/dvsim/SimCfg.py +++ b/util/dvsim/SimCfg.py @@ -103,6 +103,7 @@ def __init__(self, flow_cfg_file, hjson_data, args, mk_config): self.flow_makefile = "" self.pre_build_cmds = [] self.post_build_cmds = [] + self.post_build_opts = [] self.build_dir = "" self.pre_run_cmds = [] self.post_run_cmds = [] @@ -256,6 +257,7 @@ def _create_objects(self): self.pre_build_cmds.extend(build_mode_obj.pre_build_cmds) self.post_build_cmds.extend(build_mode_obj.post_build_cmds) self.build_opts.extend(build_mode_obj.build_opts) + self.post_build_opts.extend(build_mode_obj.post_build_opts) self.pre_run_cmds.extend(build_mode_obj.pre_run_cmds) self.post_run_cmds.extend(build_mode_obj.post_run_cmds) self.run_opts.extend(build_mode_obj.run_opts) @@ -375,9 +377,9 @@ def _match_items(items: list, patterns: list): # Merge the global build and run opts Test.merge_global_opts(self.run_list, self.pre_build_cmds, self.post_build_cmds, self.build_opts, - self.pre_run_cmds, self.post_run_cmds, - self.run_opts, self.sw_images, - self.sw_build_opts) + self.post_build_opts, self.pre_run_cmds, + self.post_run_cmds, self.run_opts, + self.sw_images, self.sw_build_opts) # Process reseed override and create the build_list build_list_names = [] diff --git a/util/dvsim/Test.py b/util/dvsim/Test.py index dc464e8e39332..d73899d00e352 100644 --- a/util/dvsim/Test.py +++ b/util/dvsim/Test.py @@ -117,15 +117,17 @@ def create_tests(tdicts, sim_cfg): @staticmethod def merge_global_opts(tests, global_pre_build_cmds, global_post_build_cmds, - global_build_opts, global_pre_run_cmds, - global_post_run_cmds, global_run_opts, - global_sw_images, global_sw_build_opts): + global_build_opts, global_post_build_opts, + global_pre_run_cmds, global_post_run_cmds, + global_run_opts, global_sw_images, + global_sw_build_opts): processed_build_modes = set() for test in tests: if test.build_mode.name not in processed_build_modes: test.build_mode.pre_build_cmds.extend(global_pre_build_cmds) test.build_mode.post_build_cmds.extend(global_post_build_cmds) test.build_mode.build_opts.extend(global_build_opts) + test.build_mode.post_build_opts.extend(global_post_build_opts) processed_build_modes.add(test.build_mode.name) test.pre_run_cmds.extend(global_pre_run_cmds) test.post_run_cmds.extend(global_post_run_cmds) diff --git a/util/dvsim/modes.py b/util/dvsim/modes.py index 0b42e7b6ca6c9..a883b15aff7d0 100644 --- a/util/dvsim/modes.py +++ b/util/dvsim/modes.py @@ -241,6 +241,7 @@ def __init__(self, bdict): self.post_build_cmds = [] self.en_build_modes = [] self.build_opts = [] + self.post_build_opts = [] self.build_timeout_mins = None self.pre_run_cmds = [] self.post_run_cmds = []