diff --git a/bin/clonetb b/bin/clonetb index 63157fc7ea..64301fc2e2 100755 --- a/bin/clonetb +++ b/bin/clonetb @@ -81,7 +81,7 @@ clone() { clone_cv32e40x() { CV_CORE=cv32e40x VERIF_ENV_REPO=https://github.com/openhwgroup/cv32e40x-dv.git - VERIF_ENV_REF=be17b8902002f91803abde4bfb8caa91088575e1 + VERIF_ENV_REF=1ceaede5f4c0da6f1d34f4f4f7d7f3bbcdbe0b4a clone ignore_cloned_directory diff --git a/bin/merge.sh b/bin/merge.sh index fb132049eb..e7e2e8bbdf 100755 --- a/bin/merge.sh +++ b/bin/merge.sh @@ -40,6 +40,16 @@ usage() { } +die() { + + scriptname=$0 + message=$1 + echo "$scriptname: error: $message" + exit 1 + +} + + merge_cv32e40s_into_cv32e40x-dv () { echo $'\n======= Merge of cv32e40s into cv32e40x-dv: =======\n' @@ -158,8 +168,8 @@ rejection_diff() { branch_name_merge_normal=$(git branch | grep 'merge') branch_name_merge_theirs=$(echo $branch_name_merge_normal | sed 's/merge/theirs/') - git checkout main - git checkout -B $branch_name_merge_theirs + git checkout main || die "can't checkout main" + git checkout -B $branch_name_merge_theirs || die "can't create branch" git merge -X theirs $branch_name_40s_subtree move_files_40s_into_40x diff --git a/cv32e40s/bsp/bsp.h b/cv32e40s/bsp/bsp.h index b257d6ce85..ca3035146f 100644 --- a/cv32e40s/bsp/bsp.h +++ b/cv32e40s/bsp/bsp.h @@ -142,7 +142,7 @@ typedef union { volatile uint32_t r : 1; volatile uint32_t w : 1; volatile uint32_t x : 1; - volatile uint32_t a : 1; + volatile uint32_t a : 2; volatile uint32_t reserved_6_5 : 2; volatile uint32_t l : 1; } __attribute__((packed)) volatile fields; @@ -163,3 +163,22 @@ typedef union { } __attribute__((packed)) volatile fields; volatile uint32_t raw : 32; } __attribute__((packed)) jvt_t; + +typedef union { + struct { + volatile uint32_t exccode : 12; + volatile uint32_t res_30_12 : 19; + volatile uint32_t interrupt : 1; + } __attribute__((packed)) volatile clint; + struct { + volatile uint32_t exccode : 12; + volatile uint32_t res_15_12 : 4; + volatile uint32_t mpil : 8; + volatile uint32_t res_26_24 : 3; + volatile uint32_t mpie : 1; + volatile uint32_t mpp : 2; + volatile uint32_t minhv : 1; + volatile uint32_t interrupt : 1; + } __attribute__((packed)) volatile clic; + volatile uint32_t raw : 32; +} __attribute__((packed)) mcause_t; diff --git a/cv32e40s/bsp/corev_uvmt.h b/cv32e40s/bsp/corev_uvmt.h index d7022b3ca7..94d73856d0 100644 --- a/cv32e40s/bsp/corev_uvmt.h +++ b/cv32e40s/bsp/corev_uvmt.h @@ -25,25 +25,27 @@ #define CV_VP_REGISTER_BASE 0x00800000 -#define CV_VP_VIRTUAL_PRINTER_OFFSET 0x00000000 -#define CV_VP_RANDOM_NUM_OFFSET 0x00000040 -#define CV_VP_CYCLE_COUNTER_OFFSET 0x00000080 -#define CV_VP_STATUS_FLAGS_OFFSET 0x000000c0 -#define CV_VP_FENCEI_TAMPER_OFFSET 0x00000100 -#define CV_VP_INTR_TIMER_OFFSET 0x00000140 -#define CV_VP_DEBUG_CONTROL_OFFSET 0x00000180 -#define CV_VP_OBI_SLV_RESP_OFFSET 0x000001c0 -#define CV_VP_SIG_WRITER_OFFSET 0x00000200 +#define CV_VP_VIRTUAL_PRINTER_OFFSET 0x00000000 +#define CV_VP_RANDOM_NUM_OFFSET 0x00000040 +#define CV_VP_CYCLE_COUNTER_OFFSET 0x00000080 +#define CV_VP_STATUS_FLAGS_OFFSET 0x000000c0 +#define CV_VP_FENCEI_TAMPER_OFFSET 0x00000100 +#define CV_VP_INTR_TIMER_OFFSET 0x00000140 +#define CV_VP_DEBUG_CONTROL_OFFSET 0x00000180 +#define CV_VP_OBI_SLV_RESP_OFFSET 0x000001c0 +#define CV_VP_SIG_WRITER_OFFSET 0x00000200 +#define CV_VP_OBI_ERR_AWAIT_GOAHEAD_OFFSET 0x00000240 -#define CV_VP_VIRTUAL_PRINTER_BASE (CV_VP_REGISTER_BASE + CV_VP_VIRTUAL_PRINTER_OFFSET) -#define CV_VP_RANDOM_NUM_BASE (CV_VP_REGISTER_BASE + CV_VP_RANDOM_NUM_OFFSET) -#define CV_VP_CYCLE_COUNTER_BASE (CV_VP_REGISTER_BASE + CV_VP_CYCLE_COUNTER_OFFSET) -#define CV_VP_STATUS_FLAGS_BASE (CV_VP_REGISTER_BASE + CV_VP_STATUS_FLAGS_OFFSET) -#define CV_VP_INTR_TIMER_BASE (CV_VP_REGISTER_BASE + CV_VP_INTR_TIMER_OFFSET) -#define CV_VP_DEBUG_CONTROL_BASE (CV_VP_REGISTER_BASE + CV_VP_DEBUG_CONTROL_OFFSET) -#define CV_VP_OBI_SLV_RESP_BASE (CV_VP_REGISTER_BASE + CV_VP_OBI_SLV_RESP_OFFSET) -#define CV_VP_SIG_WRITER_BASE (CV_VP_REGISTER_BASE + CV_VP_SIG_WRITER_OFFSET) -#define CV_VP_FENCEI_TAMPER_BASE (CV_VP_REGISTER_BASE + CV_VP_FENCEI_TAMPER_OFFSET) +#define CV_VP_CYCLE_COUNTER_BASE (CV_VP_REGISTER_BASE + CV_VP_CYCLE_COUNTER_OFFSET) +#define CV_VP_DEBUG_CONTROL_BASE (CV_VP_REGISTER_BASE + CV_VP_DEBUG_CONTROL_OFFSET) +#define CV_VP_FENCEI_TAMPER_BASE (CV_VP_REGISTER_BASE + CV_VP_FENCEI_TAMPER_OFFSET) +#define CV_VP_INTR_TIMER_BASE (CV_VP_REGISTER_BASE + CV_VP_INTR_TIMER_OFFSET) +#define CV_VP_OBI_ERR_AWAIT_GOAHEAD_BASE (CV_VP_REGISTER_BASE + CV_VP_OBI_ERR_AWAIT_GOAHEAD_OFFSET) +#define CV_VP_OBI_SLV_RESP_BASE (CV_VP_REGISTER_BASE + CV_VP_OBI_SLV_RESP_OFFSET) +#define CV_VP_RANDOM_NUM_BASE (CV_VP_REGISTER_BASE + CV_VP_RANDOM_NUM_OFFSET) +#define CV_VP_SIG_WRITER_BASE (CV_VP_REGISTER_BASE + CV_VP_SIG_WRITER_OFFSET) +#define CV_VP_STATUS_FLAGS_BASE (CV_VP_REGISTER_BASE + CV_VP_STATUS_FLAGS_OFFSET) +#define CV_VP_VIRTUAL_PRINTER_BASE (CV_VP_REGISTER_BASE + CV_VP_VIRTUAL_PRINTER_OFFSET) // -------------------------------------------------------------------------- // Registers inside the OBI_SLV_RESP VP diff --git a/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.csv b/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.csv index 5bb219791d..715c024e60 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.csv +++ b/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.csv @@ -82,7 +82,7 @@ Note: this functionality is closely matched with items mentioned in other featur Note: 40s implementation follows the example sequence in the Zc spec. ISS's should match this. (the order might change) -Coverage note: cross between possible register lists and exception arriving between/at all sub-operations would be optimal",Check against ISS,Directed Non-Self-Checking,Testcase,"Coverage hole, evaluate priority",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Coverage note: cross between possible register lists and exception arriving between/at all sub-operations would be optimal",Check against ISS,Directed Non-Self-Checking,Testcase,DTC: pma,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,cm.pop,"Destroy stack frame: load ra and 0 to 12 saved registers from the stack frame, deallocate the stack frame.",Verify all possible variations of rlist,Check against ISS,Constrained-Random,Functional Coverage,"Imperas generated coverage, hierarchy path: uvmt_cv32e40s_tb.imperas_dv.idv_trace2cov.cov_1.obj_[instr]",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,Verify all possible variations of spimm,Check against ISS,Constrained-Random,Functional Coverage,corev_rand_interrupt++,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, @@ -95,7 +95,7 @@ Note: this functionality is closely matched with items mentioned in other featur Note: 40s implementation follows the example sequence in the Zc spec. ISS's should match this. -Coverage note: cross between possible register lists and exception arriving between/at all sub-operations would be optimal",Check against ISS,Directed Non-Self-Checking,Testcase,"Coverage hole, evaluate priority",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Coverage note: cross between possible register lists and exception arriving between/at all sub-operations would be optimal",Check against ISS,Directed Non-Self-Checking,Testcase,DTC: pma,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,cm.popret,"Destroy stack frame: load ra and 0 to 12 saved registers from the stack frame, deallocate the stack frame, return to ra.",Verify all possible variations of rlist,Check against ISS,Constrained-Random,Functional Coverage,"Imperas generated coverage, hierarchy path: uvmt_cv32e40s_tb.imperas_dv.idv_trace2cov.cov_1.obj_[instr]",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,Verify all possible variations of spimm,Check against ISS,Constrained-Random,Functional Coverage,corev_rand_interrupt++,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, @@ -107,7 +107,7 @@ Note: this functionality is closely matched with items mentioned in other featur Note: 40s implementation follows the example sequence in the Zc spec. ISS's should match this. -Coverage note: cross between possible register lists and exception arriving between/at all sub-operations would be optimal",Check against ISS,Directed Non-Self-Checking,Testcase,"Coverage hole, evaluate priority",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Coverage note: cross between possible register lists and exception arriving between/at all sub-operations would be optimal",Check against ISS,Directed Non-Self-Checking,Testcase,"""push"" and ""pop"" instructions tested, testing every type of instruction is deprioritized",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,cm.popretz,"Destroy stack frame: load ra and 0 to 12 saved registers from the stack frame, deallocate the stack frame, move zero into a0, return to ra.",Verify all possible variations of rlist,Check against ISS,Constrained-Random,Functional Coverage,"Imperas generated coverage, hierarchy path: uvmt_cv32e40s_tb.imperas_dv.idv_trace2cov.cov_1.obj_[instr]",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,Verify all possible variations of spimm,Check against ISS,Constrained-Random,Functional Coverage,corev_rand_interrupt++,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, @@ -119,7 +119,7 @@ Note: this functionality is closely matched with items mentioned in other featur Note: 40s implementation follows the example sequence in the Zc spec. ISS's should match this. -Coverage note: cross between possible register lists and exception arriving between/at all sub-operations would be optimal",Check against ISS,Constrained-Random,Functional Coverage,"Coverage hole, evaluate priority",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Coverage note: cross between possible register lists and exception arriving between/at all sub-operations would be optimal",Check against ISS,Constrained-Random,Functional Coverage,"""push"" and ""pop"" instructions tested, testing every type of instruction is deprioritized",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,cm.mva01s,Move a0-a1 into two registers of s0-s7,"Verify all possible variatons of sreg1, sreg2. Note that sreg1 = sreg2 is illegal",Check against ISS,Constrained-Random,Functional Coverage,"Imperas generated coverage, hierarchy path: uvmt_cv32e40s_tb.imperas_dv.idv_trace2cov.cov_1.obj_[instr]",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,"Verify interrupts(maskable and non-maskable), debug and single stepping can not stop execution after the instruction has started to change state. Make sure external interrupts happen at all stages of execution. Expect atomic execution",Check against ISS,Directed Non-Self-Checking,Testcase,"Covered in directed test ""zc_test""",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, @@ -141,7 +141,7 @@ Note: this functionality is closely matched with items mentioned in other featur Note: 40s implementation follows the example sequence in the Zc spec. ISS's should match this. -Coverage note: cross between possible register lists and exception arriving between/at all sub-operations would be optimal",Check against ISS,Directed Non-Self-Checking,Testcase,"Coverage hole, evaluate priority",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Coverage note: cross between possible register lists and exception arriving between/at all sub-operations would be optimal",Check against ISS,Directed Non-Self-Checking,Testcase,"""push"" and ""pop"" instructions tested, testing every type of instruction is deprioritized",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,"Zcmt @@ -153,7 +153,7 @@ Note: Deprioritize as this is furthest from ratification ",cm.jt,jump via table without link,Verify all possible variations of index,Check against ISS,Constrained-Random,Functional Coverage,"Imperas generated coverage, hierarchy path: uvmt_cv32e40s_tb.imperas_dv.idv_trace2cov.cov_1.obj_[instr]",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,"Verify interrupts(maskable and non-maskable), debug and single stepping can not stop execution after the instruction has started to change state. Make sure external interrupts happen at all stages of execution. Expect atomic execution",Assertion Check,"ENV capability, not specific test",Assertion Coverage,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.controller_i.controller_fsm_i.controller_fsm_sva.a_no_sequence_interrupt,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,Verify all table jump-related fetches are checked by PMP/PMA. Specifically break/follow the rules for both systems,Check against ISS,Directed Non-Self-Checking,Testcase,"Coverage hole, evaluate priority",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,Verify all table jump-related fetches are checked by PMP/PMA. Specifically break/follow the rules for both systems,Check against ISS,Directed Non-Self-Checking,Testcase,DTC: zcmt_test,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,cm.jalt,jump via table and link to ra,Verify all possible variations of index,Check against ISS,Constrained-Random,Functional Coverage,"Imperas generated coverage, hierarchy path: uvmt_cv32e40s_tb.imperas_dv.idv_trace2cov.cov_1.obj_[instr]",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,"Verify interrupts(maskable and non-maskable), debug and single stepping can not stop execution after the instruction has started to change state. Make sure external interrupts happen at all stages of execution. Expect atomic execution",Assertion Check,"ENV capability, not specific test",Assertion Coverage,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.controller_i.controller_fsm_i.controller_fsm_sva.a_no_sequence_interrupt,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.json b/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.json index cb0c943680..b58b9d3ce3 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.json +++ b/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.json @@ -332,7 +332,7 @@ "Pass/Fail Criteria": "Check against ISS", "Test Type": "Directed Non-Self-Checking", "Coverage Method": "Testcase", - "Link to Coverage": "Coverage hole, evaluate priority", + "Link to Coverage": "DTC: pma", "": "" }, { @@ -404,7 +404,7 @@ "Pass/Fail Criteria": "Check against ISS", "Test Type": "Directed Non-Self-Checking", "Coverage Method": "Testcase", - "Link to Coverage": "Coverage hole, evaluate priority", + "Link to Coverage": "DTC: pma", "": "" }, { @@ -464,7 +464,7 @@ "Pass/Fail Criteria": "Check against ISS", "Test Type": "Directed Non-Self-Checking", "Coverage Method": "Testcase", - "Link to Coverage": "Coverage hole, evaluate priority", + "Link to Coverage": "\"push\" and \"pop\" instructions tested, testing every type of instruction is deprioritized", "": "" }, { @@ -524,7 +524,7 @@ "Pass/Fail Criteria": "Check against ISS", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "Link to Coverage": "Coverage hole, evaluate priority", + "Link to Coverage": "\"push\" and \"pop\" instructions tested, testing every type of instruction is deprioritized", "": "" }, { @@ -620,7 +620,7 @@ "Pass/Fail Criteria": "Check against ISS", "Test Type": "Directed Non-Self-Checking", "Coverage Method": "Testcase", - "Link to Coverage": "Coverage hole, evaluate priority", + "Link to Coverage": "\"push\" and \"pop\" instructions tested, testing every type of instruction is deprioritized", "": "" }, { @@ -656,7 +656,7 @@ "Pass/Fail Criteria": "Check against ISS", "Test Type": "Directed Non-Self-Checking", "Coverage Method": "Testcase", - "Link to Coverage": "Coverage hole, evaluate priority", + "Link to Coverage": "DTC: zcmt_test", "": "" }, { diff --git a/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.xlsx b/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.xlsx index 6ebd06788c..c1dccad207 100644 Binary files a/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.xlsx and b/cv32e40s/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.xlsx differ diff --git a/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.csv b/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.csv index 1b3d08821e..a5e792d808 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.csv +++ b/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.csv @@ -174,7 +174,9 @@ The only supported match types are ""address match"" for {instr execution, load, Data matching is not supported (only addr matching), so ""mcontrol6.select"" is always 0.","Configure triggers for load/store/execute and combinations of them, configure tdata2, cause triggers to fire and check that debug mode is entered correctly. All of these configurations must be crossed, also against match conditions.",Self Checking Test,Directed Self-Checking,Testcase,DTC: debug_test_trigger,?,"""tdata3"" and ""tcontrol"" should be removed.",? ,,,,,,Assertion Check,Other,Assertion Coverage,"A: a_dt_instr_trigger_hit_*, a_dt_load_trigger_hit_*, a_dt_store_trigger_hit_*. ",?,?,? User Manual v0.9.0.,,,trigger csrs,Some fields in the trigger csrs are hardwired.,Check that the tied fields are tied.,Assertion Check,Other,Assertion Coverage,"A: a_dt_tie_offs_tselect, a_dt_tie_offs_tdata1_mcontrol, a_dt_tie_offs_tdata1_etrigger, a_dt_tie_offs_tdata1_mcontrol6, a_dt_tie_offs_tdata1_disabled, a_dt_tie_offs_tdata2_etrigger. a_dt_tie_offs_tinfo.",,, -,,,"""mcontrol6"" atomics","40X, ""mcontrol6"" trigger behavior has specific descriptions for ""A"" extension.","40X, TODO this section must be filled out when the time comes for planning atomics verification.",,,,,?,?,? +,,,"""mcontrol6"" and ""mcontrol"" atomics","40X, ""mcontrol"" and ""mcontrol6"" trigger behavior has specific descriptions for ""A"" extension.","40X, TODO AMO.",Assertion Check,Other,Assertion Coverage,Not yet prioritized (TODO).,,, +,,,,"LR.W have same trigger match rules as any other loads, no matter what the destination register is. ","Inspect that LR.W is treated like any other load instruction, no matter what the destination register is.",N/A,Other,inspection,This seems to be correct. And incorrect behaviour should therefore be triggered by the a_dt_load_trigger_hit_* assertions,,, +,,,,"SC.W have same trigger match rules as any other store, no matter if it is successful or failing.","Inspect that SC.W is treated like any other store instruction, no matter if it is successful or failing.",N/A,Other,Assertion Coverage/inspection,This seems to be correct. And incorrect behaviour should therefore be triggered by the a_dt_store_trigger_hit_* assertions,?,?,? "40S User Manual Debug 1.0.0","Control and Status Registers @@ -395,9 +397,8 @@ Machine Status Registers",MPRV,,"""dcsr.mprven"" is WARL 1. Since ""mprven"" is 1, then ""mstatus.MPRV"" always takes effect in D-mode.","Read ""dcsr.mprven"", check that it is always 1. 40S, be in debug mode, have ""mstatus.MPRV"" disabled, check that all instructions are treated as M-mode. Be in debug mode, have ""mstatus.MPRV"" enabled, have ""mstatus.MPP"" set to M/U-mode (different runs), check that instructions take effect with the modified privilege mode.",Assertion Check,Other,Assertion Coverage,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.umode_assert_i.a_mprven_tied,?,?,? -Silabs Internal,,Instruction boundaries,Haltreq and stepping,"External debug requests and single stepping can only cause debug entry on ""instruction boundaries"", so a multi-step instruction cannot be interrupted by this.","While single stepping, execute misaligned loads/stores, push/pops, and table jumps, cause an external debug request while the instruction has started its sub operations, check that the external debug request does not interrupt the instructions.",Self Checking Test,Directed Self-Checking,Testcase,TODO: not covered,?,?,? -Debug 1.0.0,,Instruction boundaries,Synchronous entry,"Trigger matching can cause synchronous debug entry, and can interrupt ""within"" and instruction.","Set up triggers to match the following scenario, execute misaligned loads/stores, push/pops, and table jumps, have a trigger fire while the instruction has started its sub operations, check that the instruction gets interrupted ""midway"" and that debug mode is entered correctly.",Self Checking Test,Directed Self-Checking,Testcase,"DTC: pushpop_debug_triggers -TODO: Increase coverage by checking triggers at first/last operation",?,?,? +Silabs Internal,,Instruction boundaries,Haltreq and stepping,"External debug requests and single stepping can only cause debug entry on ""instruction boundaries"", so a multi-step instruction cannot be interrupted by this.","While single stepping, execute misaligned loads/stores, push/pops, and table jumps, cause an external debug request while the instruction has started its sub operations, check that the external debug request does not interrupt the instructions.",Self Checking Test,Directed Self-Checking,Testcase,"Covered in DTC ""debug_test2""",?,?,? +Debug 1.0.0,,Instruction boundaries,Synchronous entry,"Trigger matching can cause synchronous debug entry, and can interrupt ""within"" and instruction.","Set up triggers to match the following scenario, execute misaligned loads/stores, push/pops, and table jumps, have a trigger fire while the instruction has started its sub operations, check that the instruction gets interrupted ""midway"" and that debug mode is entered correctly.",Self Checking Test,Directed Self-Checking,Testcase,DTC: pushpop_debug_triggers,?,?,? "RISC-V External Debug Support Version 0.13.2 CV32E40P doc rev 46711ac","4.8.1 DCSR diff --git a/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.json b/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.json index e0406a6e24..fc4be8661c 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.json +++ b/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.json @@ -468,13 +468,43 @@ "Reference document": "", "Requirement Location": "", "Feature": "Trigger module", - "Sub Feature": "\"mcontrol6\" atomics", - "Feature Description": "40X, \"mcontrol6\" trigger behavior has specific descriptions for \"A\" extension.", - "Verification Goal": "40X, TODO this section must be filled out when the time comes for planning atomics verification.", - "Pass/Fail Criteria": "", - "Test Type": "", - "Coverage Method": "", - "Link to Coverage": "", + "Sub Feature": "\"mcontrol6\" and \"mcontrol\" atomics", + "Feature Description": "40X, \"mcontrol\" and \"mcontrol6\" trigger behavior has specific descriptions for \"A\" extension.", + "Verification Goal": "40X, TODO AMO.", + "Pass/Fail Criteria": "Assertion Check", + "Test Type": "Other", + "Coverage Method": "Assertion Coverage", + "Link to Coverage": "Not yet prioritized (TODO).", + "Review (Marton)": "", + "Review (Robin)": "", + "Review (Henrik)": "" + }, + { + "Reference document": "", + "Requirement Location": "", + "Feature": "Trigger module", + "Sub Feature": "", + "Feature Description": "LR.W have same trigger match rules as any other loads, no matter what the destination register is. ", + "Verification Goal": "Inspect that LR.W is treated like any other load instruction, no matter what the destination register is.", + "Pass/Fail Criteria": "N/A", + "Test Type": "Other", + "Coverage Method": "inspection", + "Link to Coverage": "This seems to be correct. And incorrect behaviour should therefore be triggered by the a_dt_load_trigger_hit_* assertions", + "Review (Marton)": "", + "Review (Robin)": "", + "Review (Henrik)": "" + }, + { + "Reference document": "", + "Requirement Location": "", + "Feature": "Trigger module", + "Sub Feature": "", + "Feature Description": "SC.W have same trigger match rules as any other store, no matter if it is successful or failing.", + "Verification Goal": "Inspect that SC.W is treated like any other store instruction, no matter if it is successful or failing.", + "Pass/Fail Criteria": "N/A", + "Test Type": "Other", + "Coverage Method": "Assertion Coverage/inspection", + "Link to Coverage": "This seems to be correct. And incorrect behaviour should therefore be triggered by the a_dt_store_trigger_hit_* assertions", "Review (Marton)": "?", "Review (Robin)": "?", "Review (Henrik)": "?" @@ -1614,7 +1644,7 @@ "Pass/Fail Criteria": "Self Checking Test", "Test Type": "Directed Self-Checking", "Coverage Method": "Testcase", - "Link to Coverage": "TODO: not covered", + "Link to Coverage": "Covered in DTC \"debug_test2\"", "Review (Marton)": "?", "Review (Robin)": "?", "Review (Henrik)": "?" @@ -1629,7 +1659,7 @@ "Pass/Fail Criteria": "Self Checking Test", "Test Type": "Directed Self-Checking", "Coverage Method": "Testcase", - "Link to Coverage": "DTC: pushpop_debug_triggers\nTODO: Increase coverage by checking triggers at first/last operation", + "Link to Coverage": "DTC: pushpop_debug_triggers", "Review (Marton)": "?", "Review (Robin)": "?", "Review (Henrik)": "?" diff --git a/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.xlsx b/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.xlsx index a8541ecae3..5cae8ed455 100644 Binary files a/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.xlsx and b/cv32e40s/docs/VerifPlans/Simulation/debug-trace/CV32E40XS_debug.xlsx differ diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv index 63683ff06a..5c9e6559a6 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv +++ b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv @@ -14,7 +14,7 @@ UM v0.3.0 Common,Constraints,Privilege Modes,CLIC interrupts only support machin Assume on input for formal",Assertion Check,"ENV capability, not specific test",Functional Coverage,a_clic_mode_only UM v0.3.0 Common,Constraints,NMI,"NMI address is located at the 15th entry in the machine trap vector table, located at mtvec. In other words, nmi_addr = { mtvec[31:7], 5'b0_1111, 2'b00 }","Assert that nmi addr = { mtvec[31:7], 5'b0_1111, 2'b00 }",Assertion Check,"ENV capability, not specific test",Functional Coverage,a_nmi_to_mtvec_offset UM v0.3.0 Common,Constraints,Interrupts,Support up to a maximum of 1024 CLIC interrupts,Assert that SMCLIC_ID_WIDTH is inside { 1 .. 10 },Assertion Check,"ENV capability, not specific test",Functional Coverage,a_clic_valid_setting -UM v0.3.0 Common,Constraints,Interrupts,Interrupt levels inside { 0 .. 255 },Correct functionality of interrupts of all valid levels,Check against RM,Constrained-Random,Functional Coverage,"Missing covergroup, vc should use all interrupt levels" +UM v0.3.0 Common,Constraints,Interrupts,Interrupt levels inside { 0 .. 255 },Correct functionality of interrupts of all valid levels,Check against RM,Constrained-Random,Functional Coverage,clic_cg.cp_lvl UM v0.3.0 Common,Constraints,Input ports,irq_i[31:0] tied to zero,Assert that non-clic irq[31:0] signals are tied to 0,Assertion Check,"ENV capability, not specific test",Functional Coverage,a_tieoff_zero_irq_i Silabs Internal,Eventually taken,Interrupt taken,"An interrupt that is both pending and enabled shall be taken, unless if the core is in debug mode or is blocked by external interfaces (rvalid, fence_flush_ack, etc), and the taking happens within a fixed number of cycles","Check that when conditions are right, then the interrupt gets taken within expected time",Assertion Check,"ENV capability, not specific test",Functional Coverage,"Waived on top level verification due to lack of visibility and precise specification of what prevents interrupts from being taken, and there exist no definite bound. @@ -58,7 +58,7 @@ CLIC 8675ec,Interrupt CSR,mtvt,"Function ptr reads treated as instruction fetch, Note, instruction fetch is treated as an implicit read, thus do not require PMP read permissions, but execute permission is required. -Both the pointer fetch and the fetch of the actual instruction located at the pointer address should be covered by the above restrictions. ",Assertion Check,"ENV capability, not specific test",Functional Coverage,TODO: Directed clic test should add case to test this +Both the pointer fetch and the fetch of the actual instruction located at the pointer address should be covered by the above restrictions. ",Assertion Check,"ENV capability, not specific test",Functional Coverage,"clic::invalid_mtvt_ptr_exec_mret, minhv_pma_block.c" UM v0.3.0 Common,Interrupt CSR,mtvt,"Always aligned to 2^(max(6, 2+SMCLIC_ID_WIDTH)","Assert that mtvt [max(6, 2+SMCLIC_ID_WIDTH)-1:0] = 0",Assertion Check,"ENV capability, not specific test",Functional Coverage,a_mtvt_alignment_correct CLIC 8675ec,Interrupt CSR,mtvt,"Determine alignment by software access, Write ones to lower order bits and read back",Test that correct alignment can be inferred by writing to these fields and read back.,Self Checking Test,Directed Self-Checking,Testcase,clic :: w_mtvt_rd_alignment diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json index 31fe7aaf06..ed0491458a 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json +++ b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json @@ -85,7 +85,7 @@ "Pass/Fail Criteria": "Check against RM", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "Link to Coverage": "Missing covergroup, vc should use all interrupt levels" + "Link to Coverage": "clic_cg.cp_lvl" }, { "Requirement Location": "UM v0.3.0 Common", @@ -338,7 +338,7 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", "Coverage Method": "Functional Coverage", - "Link to Coverage": "TODO: Directed clic test should add case to test this" + "Link to Coverage": "clic::invalid_mtvt_ptr_exec_mret, minhv_pma_block.c" }, { "Requirement Location": "UM v0.3.0 Common", diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx index 73ee087bab..9af84b6604 100644 Binary files a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx and b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx differ diff --git a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.csv b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.csv index b73b1938cf..55569d0bcb 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.csv +++ b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.csv @@ -319,7 +319,7 @@ COV: *.pma_cov_data_i.gen_rvfi_cg.cover_item_covergroup_cg_rvfi_inst_rvfi_cg_cro COV: *.pma_cov_instr_i.cover_item_covergroup_cg_mpu_inst_mpu_cg_cross_x_allow_jvt_*","TODO missing random test? Note: This is not maximally comprehensive, but the modelling that would otherwise be required is disproportionately complex." -Zce spec. proposal,,,"Instruction fetch exceptions occurring when executing an address in the jump table should lead to mepc being set to the C.TBLJ* instruction, and mtval to the address in the jump table entry",Verify that an instruction fetch exception resulting from a jump table entry leads to mepc being set to the C.TBLJ* instruction and mtval to the address in the jump table entry.,Self Checking Test,Directed Self-Checking,Testcase,DTC: TODO,TODO missing directed test? +Zce spec. proposal,,,"Instruction fetch exceptions occurring when executing an address in the jump table should lead to mepc being set to the C.TBLJ* instruction, and mtval to the address in the jump table entry",Verify that an instruction fetch exception resulting from a jump table entry leads to mepc being set to the C.TBLJ* instruction and mtval to the address in the jump table entry.,Self Checking Test,Directed Self-Checking,Testcase,Covered in Zc verif plan, Risc-V Debug spec.,Debug mode,Single step PMA exceptions,"Any instruction fetch exception that occurs while single stepping, causes debug mode to be re-entered after PC is changed to the exception handler and the appropriate tval and cause registers are updated","Verify that instruction fetches to PMA IO regions fails, the appropriate CSRs and PC is updated to the appropriate values and debug mode is reentered. ",Self Checking Test,Directed Self-Checking,Testcase,DTC: cv32e40s/tests/programs/custom/pma_debug/, ,,Program buffer PMA exceptions,Exceptions in the program buffer should cause the program buffer code to end and cmderr set to 3 (exception error),"Verify that program buffer code attempting to fetch instructions from PMA IO region fails, PC is set to dm_exception_addr_i and cmderr is set to 3 (exception error). No other registers should be changed due to this exception.",Self Checking Test,Directed Self-Checking,Testcase,DTC: cv32e40s/tests/programs/custom/pma_debug/, 40s UM 0.8.0,DebugRange,DebugRange,"""CV32E40S overrules the PMA and PMP settings for the Debug Module region when it is in debug mode""","Attempt access within/outside the dm region, in both dmode/not, check that the combo within/dmode never gets blocked and that the other combos follow the ordinary rules.",Assertion Check,Constrained-Random,Code Coverage,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pma_assert_instr_i.a_dm_region diff --git a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.json b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.json index 15f4039e83..44b4430627 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.json +++ b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.json @@ -692,8 +692,8 @@ "Pass/Fail Criteria": "Self Checking Test", "Test Type": "Directed Self-Checking", "Coverage Method": "Testcase", - "Link to Coverage": "DTC: TODO", - "Comment": "TODO missing directed test?" + "Link to Coverage": "Covered in Zc verif plan", + "Comment": "" }, { "Requirement Location": "Risc-V Debug spec.", diff --git a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.xlsx b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.xlsx index d65209864c..2728600b5b 100644 Binary files a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.xlsx and b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.xlsx differ diff --git a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.csv b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.csv index a5ddbacddd..70665cc859 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.csv +++ b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.csv @@ -1,223 +1,305 @@ Requirement Location,Feature,Sub Feature,Feature Description,Verification Goal,Pass/Fail Criteria,Test Type,Coverage Method,High Priority?,Link to Coverage,Comment -,Comments,SmepmpOverrule,"The ""smepmp"" spec features can overrule the ""privspec"" (e.g. for locking). Both specs are included here, so be mindful that checking of certain vplan items could be conditional.",N/A,N/A,N/A,N/A,,N/A, -,,FunctionalCoverage,"Functional coverage is encouraged to be creative in capturing a broad set of possible state, and evaluate it towards the checkers, to catch aspects of pmp functionality that this vplan might have overlooked.",N/A,N/A,N/A,N/A,,N/A, -,,ImplementationChanges,"If test implementation reveals new knowledge that contradicts or augments this vplan, then the vplan should be updated.",N/A,N/A,N/A,N/A,,N/A, -,,TimeAllowance,"Some verification goals in this plan has a ""base level"" of checking plus some optional tweaks that might be tried. It is up to the testing implementation how to prioritize and potentially skip the extras, according to what time allows.",N/A,N/A,N/A,N/A,,N/A, -privspec,General,Configs,"The pmp must be tested in a wide range of configurations. That includes testing on both instruction-side and data-side, and it includes testing overlapping regions, non-overlaping, no regions, differing settings for overlapping regions, M-mode only, U-mode only, both M-mode and U-mode, etc, etc. Use functional coverage with plenty of crosses.","Run with different configs to test parameters in low/mid/high ranges and in combination with the other parameters, instantiate checking on both instruction-side and data-side, write coverage to see all relevant region overlap combinations and to see an exhaustive combination of block-level input combinations and functional-level states.",Other,"ENV capability, not specific test",Functional Coverage,,COV: ???,TODO missing cover -,,Smepmp,"Given 1) backwards-compatible reset values, and 2) no change in ""mseccfg"", then C) the PMP should be fully compatible with the privspec.","For all privspec-derived PMP assertions, check that they must hold as long as the two preconditions hold (i.e. must not be excusable/overridable by smepmp features).",Other,Other,N/A,,N/A, +N/A,Comments,SmepmpOverrule,"""smepmp"" features can overrule the ""privspec"" (e.g. locking). Both specs are included here, so be aware that certain vplan items are conditional.",N/A,N/A,N/A,N/A,No,N/A, +,,FunctionalCoverage,"Functional coverage should capture a broad set of possible state (could be compared with the checkers), to find crosses that this vplan might have overlooked.",N/A,N/A,N/A,N/A,No,N/A, +,,ImplementationChanges,"If test implementation gains new knowledge, then update this vplan when appropriate.",N/A,N/A,N/A,N/A,No,N/A, +,,TimeAllowance,"Some of the verification goals have a ""base level"" of checking plus optional tweaks. It is up to implementation to prioritize and potentially skip the extras.",N/A,N/A,N/A,N/A,No,N/A, +privspec,General,Configs,"The pmp must be tested in a wide range of configurations. That includes testing on both instruction-side and data-side, and it includes testing overlapping regions, non-overlaping, no regions, differing settings for overlapping regions, M-mode only, U-mode only, both M-mode and U-mode, etc, etc. Use functional coverage with plenty of crosses.","Run with different configs to test parameters in low/mid/high ranges and in combination with the other parameters, instantiate checking on both instruction-side and data-side. + +Cover: see all relevant region overlap combinations and to see an exhaustive combination of block-level input combinations and functional-level states.",Other,"ENV capability, not specific test",Functional Coverage,No,COV: (SKIPPED),Skipped in favor of using realease-specific configs. +,,Smepmp,"Given 1) backwards-compatible reset values, and 2) no change in ""mseccfg"", then C) the PMP should be fully compatible with the privspec.","For all privspec-derived PMP assertions, check that they must hold as long as the two preconditions hold (i.e. must not be excusable/overridable by smepmp features).",Other,Other,N/A,No,(SKIPPED),Skipped in favor of considering the normal assertions good enough and using release-specific configs. ,,UmodeAlways,"""PMP checks are applied to all accesses whose effective privilege mode is S or U, including instruction fetches in S and U mode, data accesses in S and U mode when the MPRV bit in the mstatus register is clear, and data accesses in any mode when the MPRV bit in mstatus is set and the MPP field in mstatus contains S or U."" Note: None of those scenarios should let an access bypass the pmp.","Set up the system to match each point in the listing, ensure that the pmp's decision matches all modelled expectations. -Note: Also cover when none of the listed preconditions are active and the pmp's decision can disagree with the modelled expectations.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_* +Cover: when none of the listed preconditions are active and the pmp's decision can disagree with the modelled expectations.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_* A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_* -COV: ???","(Same as for ""MmodeDeny"")" -,,DefaultNone,"""PMP can grant permissions to S and U modes, which by default have none""","Check that, out of reset, given no extraordinary reset values, and given no change to the pmp csrs, then U-mode has no access permissions.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,,"A: ??? +COV: (SKIPPED)","(Same as for ""MmodeDeny"") -DTC: cv32e40s/tests/programs/custom/pmp/",TODO missing assert +Cover is skipped because it is not essential, and we have equivalence checking of RTL vs model." +,,DefaultNone,"""PMP can grant permissions to S and U modes, which by default have none""","Given: +1) out of reset, +2) no extraordinary reset values, +3) no change to the pmp csrs. + +Then: +U-mode has no access permissions. (I.e. always excepts.)",Assertion Check,"ENV capability, not specific test",Assertion Coverage,High Priority,"A: (SKIPPED). + +DTC: cv32e40s/tests/programs/custom/pmp/","Skipped in favor of using realease-specific configs (which have ""extraordinary reset values"")." ,,DefaultFull,"""can revoke permissions from M-mode, which -by default has full permissions""","Check that, out of reset, given no extraordinary reset values, and given no change to the pmp csrs, then M-mode has full access permissions.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,,"A: ??? +by default has full permissions""","Check that, out of reset, given no extraordinary reset values, and given no change to the pmp csrs, then M-mode has full access permissions.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,No,"A: (SKIPPED) -DTC: cv32e40s/tests/programs/custom/pmp/",TODO missing assert +DTC: cv32e40s/tests/programs/custom/pmp/",Skipped in favor of the directed test and the entire test suite in general. ,Csrs,ResetRegisters,"""Writable PMP registers’ A and L fields are set to 0, unless the platform mandates a different reset value for some PMP registers’ A and L fields.""","Read the A and L values right after reset, ensure that the default reset values are 0. -Note: Should also be visible on rvfi without specifically using csr instructions.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,,"A: ??? +Note: Should also be visible on rvfi without specifically using csr instructions.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,No,"A: (SKIPPED) -DTC: cv32e40s/tests/programs/custom/pmp/",TODO missing assert +DTC: cv32e40s/tests/programs/custom/pmp/","Skipped in favor of integration-level testing w/ release-specific configs, and the directed test." ,,Warl,"""All PMP CSR fields are WARL and may be hardwired to zero"". -Note: A field shall also not change its value when an attempt is made to write an illegal value to it. (XWR is one field.)","Try writing any values to the registers and read values out of them, ensure that neither reads nor writes causes exceptions, and ensure that all read values are legal or otherwise as expected and that illegally written fields don't change.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfg_expected[*].a_cfg_expected +Note: A field shall also not change its value when an attempt is made to write an illegal value to it. (XWR is one field.)","Try writing any values to the registers and read values out of them. +Ensure that neither reads nor writes causes exceptions. +And ensure that all read values are legal or otherwise as expected and that illegally written fields don't change. + +Cover: access to all CSRs and all fields.",Assertion Check,Constrained-Random,Functional Coverage,No,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfg_expected[*].a_cfg_expected A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgwdata_legal[*].a_cfgwdata_legal A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgrdata_expected[*].a_cfgrdata_expected -COV: ???",TODO missing cover +COV: (SKIPPED)",Cover skipped because the asserts are deemed sufficient. ,,MmodeOnly,"""PMP CSRs are only accessible to M-mode.""","Try to access any of the pmp CSRs from U-mode, ensure that it always gives ""illegal instruction exception"" and that the CSRs are not updated. +Cover: For all CSRs. + Note: M-mode accesses are covered by AlwaysAccessible below.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_csrs_mmode_only -COV: ??? +COV: (SKIPPED) + +DTC: cv32e40s/tests/programs/custom/pmp/",Cover skipped because the asserts and directed test are deemed sufficient. +,,Addr34bit,"""Each PMP address register encodes bits 33–2 of a 34-bit physical address for RV32""","Ensure that when the two pmpaddr MSBs are set, then no NAPOT accesses matches. +Ensure that there are no attempted accesses to MSBs that the core should not be able to use. -DTC: cv32e40s/tests/programs/custom/pmp/","TODO missing cover (combine with ""Warl"" above)" -,,Addr34bit,"""Each PMP address register encodes bits 33–2 of a 34-bit physical address for RV32""","Ensure that when the pmpaddr MSBs are set, then no NAPOT accesses matches. Cover that all bits have been matched against (""toggle cross""). Ensure that there are no attempted accesses to MSBs that the core should not be able to use.",Assertion Check,Constrained-Random,Functional Coverage,,"A: ??? +Cover: all bits have been matched against (""toggle cross"").",Assertion Check,Constrained-Random,Functional Coverage,No,"A: (SKIPPED). -COV: ???","TODO missing assert +COV: (SKIPPED)",Assert and cover skipped in favor of model equivalence checking. +,,AddrImplemented,"""Not all physical address bits may be implemented, and so the pmpaddr registers are WARL.""","Cover: (toggle) that all bits can be both written and set. -TODO missing cover" -,,AddrImplemented,"""Not all physical address bits may be implemented, and so the pmpaddr registers are WARL.""",Cover (toggle) that all bits can be both written and set. (UnusedZero below covers the WARL(0x0) case.),Other,Constrained-Random,Functional Coverage,High Priority,COV: ???,TODO missing cover +(""UnusedZero"" below covers the WARL(0x0) case.)",Other,Constrained-Random,Functional Coverage,High Priority,COV: (SKIPPED),Skipped in favor of integration-level testing w/ release-specific configs. ,AddressMatching,MatchDisabled,"""When A=0, this PMP entry is disabled and matches no addresses"" -When a cfg is set to off but its address(es) (interpreted as napot/tor) is the only rule that matches an attempted access, then it still does not count as a match.","Have a region's address(es) set up as tor and napot (separate runs), have all other regions not include the target address, have the target region's rule be OFF, make an access within that range, ensure that the outcome is the same as for when an access is outside of all address ranges. +When a cfg is set to off but its address(es) (interpreted as napot/tor) is the only rule that matches an attempted access, then it still does not count as a match.","Have a region's address(es) set up as tor and napot (separate runs), +have all other regions not include the target address, +have the target region's rule be OFF, +make an access within that range, +ensure that the outcome is the same as for when an access is outside of all address ranges. Note: For this and several other items, functional coverage is necessary because the checking doesn't necessarily have the above scenario in its antecedent. -Coverage: Capture the above scenario, minus the checking.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal +Coverage: Capture the above scenario, minus the checking.",Assertion Check,Constrained-Random,Functional Coverage,No,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -COV: ???",TODO missing cover +COV: (SKIPPED)","Cover is skipped in favor of integration-level testing w/ release-specific configs, because we have equivalence checking of RTL vs model." ,,NapotMatching,"""NAPOT ranges make use of the low-order bits of the associated address register to encode the size of the range [""yyyy...yy01"" etc]"" -Note: The napot address matching modes match on addresses that are equal to the requested access when masked to the granularity size.","Configure napot rules of different sizes, try accesses within and outside the regions, ensure that the outcomes corresponds to the designated sizes. +Note: The napot address matching modes match on addresses that are equal to the requested access when masked to the granularity size.","Configure napot rules of different sizes. +Try accesses within and outside the regions. +Ensure that the outcomes corresponds to the designated sizes. Note: Includes NAPOT and NA4. -Note: Try also max and min.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_na4is4byte.a_na4_is_4byte +Cover: Matching inside / outside. + +Cover: Min / Max of the ""yyy..."" patterns.",Assertion Check,Constrained-Random,Functional Coverage,No,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_na4is4byte.a_na4_is_4byte A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal COV: dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_cg_common.cover_item_covergroup_cg_internals_common_inst_cg_int_coverpoint_cp_napot_encoding_bin_auto[*] -dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_cg_common.cover_item_covergroup_cg_internals_common_inst_cg_int_coverpoint_cp_napot_encoding_disallowed_bin_auto[*] -COV: ???",TODO missing coverage -,,TorMatching,"""If TOR is selected, the associated address register forms the top of the address range, and the preceding PMP address register forms the bottom of the address range. If PMP entry i’s A field is set to TOR, the entry matches any address y such that pmpaddri−1 ≤ y < pmpaddri (irrespective of the value of pmpcfgi−1)""","Configure tor regions of different sizes, try accesses within and outside the regions, ensure that the outcomes corresponds to the designated ranges.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +COV: dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_cg_common.cover_item_covergroup_cg_internals_common_inst_cg_int_coverpoint_cp_napot_encoding_disallowed_bin_auto[*] -COV: dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_cg_common.cover_item_covergroup_cg_internals_common_inst_cg_int_coverpoint_cp_ismatch_tor_bin_auto[*] +COV: (SKIPPED).",Cover skipped (min/max) in favor of model equivalence checking and trusting formal's capability of exercising the asserts. +,,TorMatching,"""If TOR is selected, the associated address register forms the top of the address range, and the preceding PMP address register forms the bottom of the address range. If PMP entry i’s A field is set to TOR, the entry matches any address y such that pmpaddri−1 ≤ y < pmpaddri (irrespective of the value of pmpcfgi−1)""","Configure tor regions of different sizes. +Try accesses within and outside the regions. +Ensure that the outcomes correspond to the designated ranges.",Assertion Check,Constrained-Random,Functional Coverage,No,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -COV: ???",TODO missing coverage -,,TorZero,"""If PMP entry 0’s A field is set to TOR, zero is used for the lower bound, and so it matches any address y < pmpaddr0.""","Configure entry 0 as tor regions of different sizes, try accesses within and outside the regions, ensure that the outcomes corresponds to the designated ranges.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -COV: ??? +COV: dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_cg_common.cover_item_covergroup_cg_internals_common_inst_cg_int_coverpoint_cp_ismatch_tor_bin_auto[*]", +,,TorZero,"""If PMP entry 0’s A field is set to TOR, zero is used for the lower bound, and so it matches any address y < pmpaddr0.""","Configure entry 0 as tor regions of different sizes, try accesses within and outside the regions, ensure that the outcomes corresponds to the designated ranges.",Assertion Check,Constrained-Random,Functional Coverage,No,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -DTC: cv32e40s/tests/programs/custom/pmp/",TODO missing cover -,,TorNomatch,"""If pmpaddri−1 ≥ pmpaddri and pmpcfgi.A=TOR, then PMP entry i matches no addresses.""","Set up tor regions where the addresses are not in increasing order, try accesses on or within the designated ""reverse"" regions, ensure that they are treated as if there is no match.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal + +COV: (SKIPPED) + +DTC: cv32e40s/tests/programs/custom/pmp/",Cover skipped in favor of directed test and equivalence checking vs model. +,,TorNomatch,"""If pmpaddri−1 ≥ pmpaddri and pmpcfgi.A=TOR, then PMP entry i matches no addresses.""","Set up tor regions where the addresses are not in increasing order, try accesses on or within the designated ""reverse"" regions, ensure that they are treated as if there is no match.",Assertion Check,Constrained-Random,Functional Coverage,No,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -COV: ??? +COV: (SKIPPED) -DTC: cv32e40s/tests/programs/custom/pmp/",TODO missing cover -,,SameGrain,"""In general, the PMP grain [...] must be the same across all PMP regions.""","Do the same as for the basic case of GranularityDetermination below, ensure that all read values are the same across all the pmp csrs.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,,A: ???,TODO missing assert +DTC: cv32e40s/tests/programs/custom/pmp/",Cover skipped in favor of directed test and equivalence checking vs model. +,,SameGrain,"""In general, the PMP grain [...] must be the same across all PMP regions.""","Do the same as for the basic case of GranularityDetermination below, ensure that all read values are the same across all the pmp csrs.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,No,A: (SKIPPED),Assert skipped in favor of the asserts checking the grain in general and model equivalence checking. ,,Na4Unselectable,"""When G ≥ 1, the NA4 mode is not selectable.""","Have the G parameter set to at least 1, ensure that NA4 never gets selected (even when writing to non-locked cfg). Note: Formal should easily check this.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_na4onlyg0[*].a_na4_only_g0 uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_na4onlyg0[*].a_na4_only_g0 A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_na4onlyg0[*].a_na4_not_when_g uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_na4onlyg0[*].a_na4_not_when_g", -,,NapotImplied,"""When G ≥ 2 and pmpcfgi.A[1] is set, i.e. the mode is NAPOT"".",(Covered by Na4Unselectable above),Other,Other,N/A,,N/A, +,,NapotImplied,"""When G ≥ 2 and pmpcfgi.A[1] is set, i.e. the mode is NAPOT"".",(Covered by Na4Unselectable above),Other,Other,N/A,High Priority,N/A, ,,NapotOnes,"""When G ≥ 2 and pmpcfgi.A[1] is set, [...] then bits pmpaddri[G-2:0] read as all ones.""","Have the G parameter set to at least 2, have A set, read pmpaddri, ensure the LSBs are all ones as specified.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_napot_ones_g2.gen_napot_ones_i[*].a_napot_ones, ,,AllZeros,"""When G ≥ 1 and pmpcfgi.A[1] is clear, i.e. the mode is OFF or TOR, then bits pmpaddri[G-1:0] read as all zeros.""","Create the listed preconditions, ensure that the read value contains zeroes as specified. Note: Check both OFF/TOR, and for all configs fields (checking of all configs don't need 100% coverage in simulation).",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_all_zeros_g1.gen_all_zeros_i[*].a_all_zeros -COV: ???",TODO missing cover -,,TorUnaffected,"""Bits pmpaddri[G-1:0] do not affect the TOR address-matching logic.""","Write different values to ""pmpaddri[G-1:0]"", ensure TOR mode matches the same either way.",Assertion Check,Constrained-Random,Assertion Coverage,,A: ???,TODO missing assert +COV: uvmt_cv32e40s_pmp_assert.sv, ""cp_ismatch_tor"". + +COV: uvmt_cv32e40s_pmp_assert.sv, ""cov_rlb_locked_rules_can_remove"".",(The covers are written for a different purpose but should sufficiently hit this.) +,,TorUnaffected,"""Bits pmpaddri[G-1:0] do not affect the TOR address-matching logic.""","Write different values to ""pmpaddri[G-1:0]"", ensure TOR mode matches the same either way.",Assertion Check,Constrained-Random,Assertion Coverage,No,A: (SKIPPED),Assert skipped in favor of model equivalence checking. ,,StorageUnaffected,"""Although changing pmpcfgi.A[1] affects the value read from pmpaddri, it does not affect the underlying value stored in that register"" -""in particular, pmpaddri[G-1] retains its original value when pmpcfgi.A is changed from NAPOT to TOR/OFF then back to NAPOT.""","Change in and out of (OFF || TOR) and !(OFF || TOR), ensure that different values can be read without having written anything new to the register.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_storage_unaffected[*].a_storage_unaffected +""in particular, pmpaddri[G-1] retains its original value when pmpcfgi.A is changed from NAPOT to TOR/OFF then back to NAPOT.""","Change in and out of (OFF || TOR) and !(OFF || TOR), ensure that different values can be read without having written anything new to the register. + +Cover: All transitions, na4/napot -> off/tor.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_storage_unaffected[*].a_storage_unaffected -COV: ???",TODO missing cover +COV: (SKIPPED)",Cover skipped because assert is deemed sufficient. ,,GranularityDetermination,"""Software may determine the PMP granularity by writing zero to pmp0cfg, then writing all ones to pmpaddr0, then reading back pmpaddr0. If G is the index of the least-significant bit set, the PMP granularity is 2 G+2 bytes.""","Write zero to pmpicfg, write ones to pmpaddri, read pmpaddri, ensure that the LSB index matches to granularity parameter. Note: Formal can maybe check this for all i. Note: If time allows, can write something else than zero and ensure that the rest follows as expected.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_granularity_determination, -,,XlenMatching,"""If the current XLEN is greater than MXLEN, the PMP address registers are zero-extended from MXLEN to XLEN bits for the purposes of address matching.""",N/A,N/A,N/A,N/A,,N/A, +,,XlenMatching,"""If the current XLEN is greater than MXLEN, the PMP address registers are zero-extended from MXLEN to XLEN bits for the purposes of address matching.""",N/A,N/A,N/A,N/A,No,N/A, ,LockingAndPrivmode,UntilReset,"""Locked PMP entries remain locked until the hart is reset.""","Lock entry i (for all i, if feasible), ensure that the lock bit is never lifted before reset. (Unless if RLB interferes.) Note: Sim might do a second reset, formal most likely won't and shouldn't need to.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_until_reset[*].a_until_reset, -,,IgnoreWrites,"""If PMP entry i is locked, writes to pmpicfg and pmpaddri are ignored.""","Lock entry i (for all i, if feasible), ensure that their value can't change, both when written to and otherwise. (Unless if RLB interferes.)",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_rlb_locked[*].a_norlb_locked_rules_cannot_modify uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_rlb_locked[*].a_norlb_locked_rules_cannot_modify +,,IgnoreWrites,"""If PMP entry i is locked, writes to pmpicfg and pmpaddri are ignored.""","Lock entry i (for all i, if feasible), ensure that their value can't change. (Unless if RLB interferes.) + +Cover: both when written to and otherwise.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_rlb_locked[*].a_norlb_locked_rules_cannot_modify uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_rlb_locked[*].a_norlb_locked_rules_cannot_modify A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_writes_notrap[*].a_ignore_writes_notrap A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_writes_nochange[*].a_ignore_writes_nochange -COV: ???",TODO missing cover -,,IgnoreTor,"""Additionally, if PMP entry i is locked and pmpicfg.A is set to TOR, writes to pmpaddri-1 are ignored.""","Lock entry i (…), have A set and the mode be TOR, ensure that pmpaddri-1 can't change, both for explicit writes and otherwise. (Unless RLB.)",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_tor[*].a_ignore_tor_stable +COV: (SKIPPED)",Cover skipped because the asserts are deemed sufficient. +,,IgnoreTor,"""Additionally, if PMP entry i is locked and pmpicfg.A is set to TOR, writes to pmpaddri-1 are ignored.""","Lock entry i (…), have A set and the mode be TOR, ensure that pmpaddri-1 can't change. (Unless RLB.) + +Cover: both for explicit writes and otherwise",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_tor[*].a_ignore_tor_stable A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_tor[*].a_ignore_tor_wdata -COV: ???",TODO missing cover -,,NotIgnore,"When neither cfg i is locked, nor is cfg i+1 a locked TOR region, then writes to cfg and addr i are not ignored.","Have cfg i unlocked, write to cfg and addr csr i, check that it changes.",Assertion Check,Constrained-Random,Assertion Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_addr_writes[*].a_addr_nonlocked +COV: (SKIPPED)",Cover skipped because the asserts are deemed sufficient. +,,NotIgnore,"When neither cfg i is locked, nor is cfg i+1 a locked TOR region, then writes to cfg and addr i are not ignored.","Have cfg i unlocked, +write to cfg and addr csr i, +check that it changes.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_addr_writes[*].a_addr_nonlocked A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_addr_tor[*].a_addr_nonlocked_tor", ,,LockOff,"""Setting the L bit locks the PMP entry even when the A field is set to OFF.""","Lock entry i while the mode is OFF, ensure that it gets locked in this case too. Note: Ensure that checking and coverage handles locking for all possible modes.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: (Same checking as for ""IgnoreWrites"" and ""IgnoreTor"" above.) -COV: ???",TODO missing cover -,,RwxPrivmode,"""In addition to locking the PMP entry, the L bit indicates whether the R/W/X permissions are enforced on M-mode accesses. When the L bit is set, these permissions are enforced for all privilege modes.""","Be in M-mode and U-mode (separate runs), access a region where L is set and where RWX {grant, deny R, deny W, deny X}, ensure that the access is correspondingly granted/denied.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +COV: (SKIPPED).","Cover skipped, trusting formal to exercise the assert." +,,RwxPrivmode,"""In addition to locking the PMP entry, the L bit indicates whether the R/W/X permissions are enforced on M-mode accesses. When the L bit is set, these permissions are enforced for all privilege modes.""","Be in M-mode and U-mode (separate runs), +access a region where L is set and where RWX {grant, deny R, deny W, deny X}, +ensure that the access is correspondingly granted/denied. -COV: ???",TODO missing cover +Cover: grant, deny R, deny W, deny X.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal + +COV: (SKIPPED)",Cover skipped because the asserts are deemed sufficient. ,,MmodeSucceed,"""When the L bit is clear, any M-mode access matching the PMP entry will succeed""","Be in M-mode, access a region where L is clear, ensure that access is granted in all cases. -(Note, see ""Smepmp"" above.)",Assertion Check,Constrained-Random,Assertion Coverage,,A: ???,TODO missing assert -,,RwxUmode,"""When the L bit is clear […] the R/W/X permissions apply only to S and U modes.""","Be in U-mode, access a region where L is clear, ensure that access is granted/denied based on RWX.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_uorl_onlyif_rwx -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_uorl_onlyif_rwx +(Note, see ""Smepmp"" above.)",Assertion Check,Constrained-Random,Assertion Coverage,No,A: (SKIPPED),Assert skipped in favor of Smepmp-based assertions. +,,RwxUmode,"""When the L bit is clear […] the R/W/X permissions apply only to S and U modes.""","Be in U-mode, access a region where L is clear, ensure that access is granted/denied based on RWX. + +Cover: granted / denied. + +Note: The M-mode part of this is handled by ""MmodeSucceed"" above.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_uorl_onlyif_rwx + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_uorl_onlyif_rwx -COV: ???",TODO missing cover +COV: (SKIPPED)",Cover skipped because the asserts are deemed sufficient. ,PriorityAndMatching,LowestDetermines,"""PMP entries are statically prioritized. The lowest-numbered PMP entry that matches any byte of an access determines whether that access succeeds or fails."" Note: ""any"" byte.","Access a region that is covered by multiple rules, ensure that the lowest indexed match determines the outcome. -Note: Requires that the rules would disagree on the outcome.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +Note: Requires that the rules would disagree on the outcome. (One rule allows, other disallows.) + +Cover: ""winning"" rule allows / disallows.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -COV: ???",TODO missing cover -,,MatchAll,"""The matching PMP entry must match all bytes of an access, or the access fails, irrespective of the L, R, W, and X bits.""",(Only relevant for 64-bit architectures.),N/A,N/A,N/A,,N/A, -,,LrwxDetermines,"""If a PMP entry matches all bytes of an access, then the L, R, W,and X bits determine whether the access succeeds or fails. [...] if the L bit is set or the privilege mode of the access is S or U, then the access succeeds only if the R, W,or X bit corresponding to the access type is set.""","Access a pmp region where L and the privmode etc is such that nothing else would deny the access, ensure that each of (or a combination of) RWX can either grant or deny the access.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_lrwx_aftermatch +COV: (SKIPPED).","Cover skipped, trusting formal to exercise the assert." +,,MatchAll,"""The matching PMP entry must match all bytes of an access, or the access fails, irrespective of the L, R, W, and X bits.""",(Only relevant for 64-bit architectures.),N/A,N/A,N/A,No,N/A, +,,LrwxDetermines,"""If a PMP entry matches all bytes of an access, then the L, R, W,and X bits determine whether the access succeeds or fails. [...] if the L bit is set or the privilege mode of the access is S or U, then the access succeeds only if the R, W,or X bit corresponding to the access type is set.""","Access a pmp region where L and the privmode etc is such that nothing else would deny the access, ensure that each of (or a combination of) RWX can either grant or deny the access. + +Cover: U, M, L, grant, deny R, deny W, deny X, etc.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_lrwx_aftermatch A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_lrwx_aftermatch -COV: ???",TODO missing cover -,,MmodeSucceed2,"""If the L bit is clear and the privilege mode of the access is M, the access succeeds.""","(Same as ""MmodeSucceed"" above)",Other,Other,N/A,,N/A, -,,MmodeNomatch,"""If no PMP entry matches an M-mode access, the access succeeds.""","Be in M-mode, access a region where no rule matches, ensure that the access is granted (where MMWP is off). +COV: (SKIPPED)","Cover skipped because the asserts are deemed sufficient. It is partially covered already by the ""general"" covergroup and its crosses." +,,MmodeSucceed2,"""If the L bit is clear and the privilege mode of the access is M, the access succeeds.""","(Same as ""MmodeSucceed"" above)",Other,Other,N/A,No,N/A, +,,MmodeNomatch,"""If no PMP entry matches an M-mode access, the access succeeds.""","Be in M-mode, +access a region where no rule matches, +ensure that the access is granted (where MMWP is off). + +Cover: the checker is generic, so cover this specific scenario. -(Note, see ""Smepmp"" above.)",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal +(Note, see ""Smepmp"" above.)",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -COV: ???",TODO missing cover +COV: uvmt_cv32e40s_pmp_assert.sv, ""cp_x_mmode_nomatch_nommwp_x"". + +COV: uvmt_cv32e40s_pmp_assert.sv, ""cp_r_mmode_nomatch_nommwp_r"". + +COV: uvmt_cv32e40s_pmp_assert.sv, ""cp_w_mmode_nomatch_nommwp_w"".", ,,UmodeNomatch,"""If no PMP entry matches an S-mode or U-mode access, but at least one PMP entry is implemented, the access fails."" -Note: ""All PMP CSRs are always implemented"".","Be in U-mode, do an access that doesn't match any region, ensure that the access fails.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_nomatch_umode_fails +Note: ""All PMP CSRs are always implemented"".","Be in U-mode, do an access that doesn't match any region, ensure that the access fails.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_nomatch_umode_fails -A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_nomatch_umode_fails +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_nomatch_umode_fails", +,,UmodeOff,"""If at least one PMP entry is implemented, but all PMP entries’ A fields are set to OFF, then all S-mode and U-mode memory accesses will fail.""","Be in U-mode, +have all entries OFF, +make an access, +ensure that the access fails. -COV: ???",TODO missing cover -,,UmodeOff,"""If at least one PMP entry is implemented, but all PMP entries’ A fields are set to OFF, then all S-mode and U-mode memory accesses will fail.""","Be in U-mode, have all entries OFF, make an access, ensure that the access fails (for all variations of accesses).",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +Cover: this specific scenario. + +Cover: for all variations of accesses",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,"A: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_umode_off"". + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -COV: ???",TODO missing cover -,,FailException,"""Failed accesses generate an instruction, load, or store access-fault exception.""","Cause failed accesses on instructions/loads/stores, ensure that an exception occurs and that it is the right one.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_* +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -A: ::uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_* +COV: (SKIPPED)","Second cover skipped because it should be the responsibility of the ""general"" covergroup and its crosses." +,,FailException,"""Failed accesses generate an instruction, load, or store access-fault exception.""","Cause failed accesses on instructions/loads/stores, ensure that an exception occurs and that it is the right one.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_* -COV: ???",TODO missing cover +A: ::uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_*", ,,MultiAccess,"""Note that a single instruction may generate multiple accesses, which may not be mutually atomic. An access-fault exception is generated if at least one access generated by an instruction fails, though other accesses generated by that instruction may succeed with visible side effects."" ""On some implementations, misaligned loads, stores, and instruction fetches may also be decomposed into multiple accesses, some of which may succeed before an access-fault exception occurs. In particular, a portion of a misaligned store that passes the PMP check may become visible, even if another portion fails the PMP check.""","Induce misaligned word instruction-fetch, load, and store, where the lower and upper (separate runs) parts are either accessible or blocked by pmp, ensure that exceptions occur while parts of the access might reach the bus. -Also check Zc's push/pop and table jump. +Cover: upper/lower blocked/allowed. -Note: It is up to other vplans to check what happens upon the exception. It is up to this PMP vplan to check that the PMP will cause the exceptions.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_splittrap +Cover: parts reaching the bus. -A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_splittrap +Cover: push/pop and table jump. + +Note: It is up to other vplans to check what happens upon the exception. It is up to this PMP vplan to check that the PMP will cause the exceptions.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec* -A: ??? +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore* -COV: ???","TODO missing assert (on split that errs on first) +A: (SKIPPED) -TODO missing cover" -smepmp,MsecCfg,MmodeOnly,"""Machine Security Configuration (mseccfg) is [...] only accessible to Machine mode."" +COV: (SKIPPED)","Assert skipped (explicitly, split that errs on first) because it is theoretically covered by the generic assert. + +Specific covers skipped, in favor of trusting formal's ability to exercise the asserts." +smepmp,MsecCfg,MmodeOnly,"""Machine SECurity ConFiGuration (mseccfg) is [...] only accessible to Machine mode."" Note: Includes ""mseccfgh"".","Access (read/write) mseccfg (and mseccfgh) from M-mode, access mseccfg from U-mode, ensure that the first always works (WARL) and the second never works (exception). -Note: Cover with MPRV too.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: ???,TODO missing assert +Note: Cover with MPRV too. + +Cover: read/write, mmode/umode, mprv/no, mseccfg/mseccfgh.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_csrs_mmode_only"". + +COV: (SKIPPED)","Cover skipped, trusting formal to exercise the assert." ,,FieldsWarl,"""All mseccfg fields defined on this proposal are WARL""","Try writing any values to the fields (the defined ones, but also other bits) and read values out of the fields, ensure that neither reads nor writes causes exceptions, and ensure that all read values are legal or otherwise as expected. Note: This relates to the ""stickiness"" of those fields. Regardless of their values and current stickiness, the fields are WARL. -Note: It might be difficult, when trying to write a checker for traps, to filter out all other causes for traps that can occur simultaneously. (Either reduce the scope of checking, or write re-usable helper signals for ""trap causality"" info.) +Note: ""WPRI"" on some bits.",Assertion Check,Constrained-Random,Functional Coverage,No,"A: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_csrs_mmode_only"". -Note: ""WPRI"" on some bits.",Assertion Check,Constrained-Random,Functional Coverage,,"A: ??? +A: (SKIPPED) -COV: ???","TODO missing assert +COV: (SKIPPED)","Second assert skipped because the features themselves are covered by other asserts and integration testing. -TODO missing cover" +Cover skipped for the same reasons as the assert and also because the covergroups in uvmt_cv32e40s_pmp_assert.sv covers parts of it." ,,ReservedZero,"""the remaining bits are reserved for future standard use and should always read zero."" -(This spec can't dictate that about other specs, but the user manual agrees on the hardwiring.)","Read mseccfg, ensure the non-smepmp-field bits are always zero.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: ???,TODO missing assert + +(Note: This spec can't dictate that about other specs, but the user manual agrees on the hardwiring.)","Read mseccfg, ensure the non-smepmp-field bits are always zero.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,"A: uvmt_cv32e40s_pmp_assert.sv, ""a_reserved_zero_mseccfg_fields"".", ,,ResetValue,"""The reset value of mseccfg is implementation-specific, otherwise if backwards compatibility is a requirement it should reset to zero on hard reset.""","Read the value of mseccfg right after reset, ensure that the default reset value is zero. Note: Should also be visible on rvfi without specifically using csr instructions.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_mseccfg_reset_val @@ -225,21 +307,21 @@ Note: Should also be visible on rvfi without specifically using csr instructions A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_mseccfg_reset_val", ,LockingBypass,ModifiableEntries,"""When mseccfg.RLB is 1 locked PMP rules may be removed/modified and locked PMP entries may be edited."" -Note: Both ""cfg"" and ""addr"" registers, limited to fields within ""cfg"" reg, also TOR affects lower ""addr"" reg.","Have a locked pmp entry i, set RLB to 1, try modifying any(!) field within {pmpicfg, pmpaddri, pmpaddri-1(tor)}, ensure that values are updated succesfully (while respecting other rules like legal values and reserved bits).",Assertion Check,Constrained-Random,Functional Coverage,,"A: ??? +Note: Both ""cfg"" and ""addr"" registers, limited to fields within ""cfg"" reg, also TOR affects lower ""addr"" reg.","Have a locked pmp entry i, set RLB to 1, try modifying any(!) field within {pmpicfg, pmpaddri, pmpaddri-1(tor)}, ensure that values are updated succesfully (while respecting other rules like legal values and reserved bits).",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: N/A -COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_addr +COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_addr -COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_exec +COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_exec -COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_lock +COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_lock -COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_mode +COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_mode -COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_read +COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_read -COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_write +COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_write -COV: ???",TODO missing assert +COV: uvmt_cv32e40s_pmp_assert.sv, ""cov_rlb_locked_rules_can_modify_tor"".",The assert is N/A because the covers are the checkers. ,,RemainZero,"""When mseccfg.RLB is 0 and pmpcfg.L is 1 in any rule or entry (including disabled entries), then mseccfg.RLB remains 0 and any further modifications to mseccfg.RLB are ignored until a PMP reset"" Note: ""any"" entry.","Have RLB=0 and at least one L=1, ensure that RLB is 0 forever (until reset). @@ -247,105 +329,159 @@ Note: ""any"" entry.","Have RLB=0 and at least one L=1, ensure that RLB is 0 for Note: No exception occurs on attempted access, but one should try overwriting the value to stimulate the checking.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_rlb_never_fall_while_locked A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_rlb_never_fall_while_locked", -,,UntilReset,"The sticky zero and update-ignores last until reset, and do not hold after reset.",Ensure that RLB is modifiable after reset. (Unless if reset values are set to activate the RemainZero condition.),Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_until_reset_notbefore +,,UntilReset,"The sticky zero and update-ignores last until reset, and do not hold after reset.","Ensure that RLB is modifiable after reset. (Unless if reset values are set to activate the RemainZero condition.) -COV: ???",TODO missing cover -,,HardwireZero,"""Vendors who don’t need this functionality may hardwire this field to 0.""","(40s has not hardwired this to 0, it is RW.)",N/A,N/A,N/A,,N/A, +Note: Both enable / disable.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_until_reset_notbefore, +,,HardwireZero,"""Vendors who don’t need this functionality may hardwire this field to 0.""","(40s has not hardwired this to 0, it is RW.)",N/A,N/A,N/A,No,N/A, ,WhiteList,StickyUntilReset,"""[mseccfg.MMWP] is a sticky bit, meaning that once set it cannot be unset until a PMP reset.""","Have MMWP set, ensure that it remains high forever (til reset).",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_mmwp_never_fall_until_reset A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_mmwp_never_fall_until_reset", -,,Denied,"""When set it changes the default PMP policy for M-mode when accessing memory regions that don’t have a matching PMP rule, to denied instead of ignored.""","Have MMWP set, be in (effective mode) M-mode, access regions that don't match any rule (including OFF, ""reversed"" TOR, >32bit NAPOT, etc), ensure that the access is denied.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_nomatch_mmode_mmwp_fails +,,Denied,"""When set it changes the default PMP policy for M-mode when accessing memory regions that don’t have a matching PMP rule, to denied instead of ignored.""","Have MMWP set, +be in (effective mode) M-mode, +access regions that don't match any rule (including OFF, ""reversed"" TOR, >32bit NAPOT, etc), +ensure that the access is denied. + +Cover: MPRV/no, off/reversed/napot.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_nomatch_mmode_mmwp_fails A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_nomatch_mmode_mmwp_fails -COV: ???",TODO missing cover -,LockdownGeneral,StickyUntilReset,"""[mseccfg.MML] is a sticky bit, meaning that once set it cannot be unset until a PMP reset.""","Cover: Trying to clear the bit. +COV: (SKIPPED)",Cover skipped because assert is deemed sufficient. +,LockdownGeneral,StickyUntilReset,"""[mseccfg.MML] is a sticky bit, meaning that once set it cannot be unset until a PMP reset.""","Check: Have MML set, ensure that it remains high forever (til reset). -Check: Have MML set, ensure that it remains high forever (til reset).",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_mml_never_fall_until_reset +Cover: Trying to clear the bit.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_mml_never_fall_until_reset A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_mml_never_fall_until_reset -COV: ???",TODO missing cover +COV: (Skipped)",Cover skipped because assert is deemed sufficient. ,,ExecIgnored,"""[When mseccfg.MML is set.] Adding an M-mode-only or a locked Shared-Region rule with executable privileges is not possible and such pmpcfg writes are ignored, leaving pmpcfg unchanged."" -Note: ""pmpcfg"" refers to a field, so the write to the CSR itself should still update other fields.","Have MML set, try adding an ""M-mode-only"" rule and a ""locked Shared-Region"" rule with X privileges, ensure that the relevant pmpcfg field is not updated but is left unchanged, ensure also that other fields can still get updated.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgwdata_legal[*].a_cfgwdata_legal +Note: ""pmpcfg"" refers to a field, so the write to the CSR itself should still update other fields.","Have MML set, +try adding an ""M-mode-only"" rule and a ""locked Shared-Region"" rule with X privileges, +ensure that the relevant pmpcfg field is not updated but is left unchanged, +ensure also that other fields can still get updated. + +Cover: M-mode-only / Shared-Region.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgwdata_legal[*].a_cfgwdata_legal A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_rlb_locked_cov[0].a_mmode_only_or_shared_executable_ignore A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_rlb_locked_cov[0].a_mmode_only_or_shared_executable_ignore -COV: ???",TODO missing cover +COV: (SKIPPED)",Cover skipped because assert is deemed sufficient. ,,ExecRlb,"""[The above] restriction can be temporarily lifted e.g. during the boot process, by setting mseccfg.RLB.""","Have RLB and MML set, try adding an ""M-mode-only"" rule and a ""locked Shared-Region"" rule with X privileges, ensure that the relevant pmpcfg field is in fact updated.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_rlblifts_lockedexec[*].a_rlblifts_lockedexec, -,,MmodeExec,"""Executing code with Machine mode privileges is only possible from memory regions with a matching M-mode-only rule or a locked Shared-Region rule with executable privileges. Executing code from a region without a matching rule or with a matching S/U-mode-only rule is denied.""","Execute from ""M-mode-only"" and ""locked Shared-Region"" regions, attempt execution without matching and from ""U-mode-only"" regions, ensure corresponding grant or deny.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +,,MmodeExec,"""Executing code with Machine mode privileges is only possible from memory regions with a matching M-mode-only rule or a locked Shared-Region rule with executable privileges. Executing code from a region without a matching rule or with a matching S/U-mode-only rule is denied.""","Execute from ""M-mode-only"" and ""locked Shared-Region"" regions, +attempt execution without matching and from ""U-mode-only"" regions, +ensure corresponding grant or deny. -COV: ???",TODO missing cover +Cover: The different scenarios.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal + +COV: (SKIPPED)",Cover skipped because assert is deemed sufficient. ,,RwReserved,"""If mseccfg.MML is not set, the combination of pmpcfg.RW=01 remains reserved for future standard use.""","Whitelist the conditions that allow RW=01 (including MML conditions), ensure that it is adhered to.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_rwx_mml[*].a_rwx_mml A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_rwfuture[*].a_rw_futureuse uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_rwfuture[*].a_rw_futureuse", -,LockdownA,MmodeEnforce,"""[When mseccfg.MML is set.] An M-mode-only rule is enforced on Machine mode""","Be in M-mode, have MML set, access an ""M-mode-only"" region, ensure that the grant/deny is always in accordance to the rule. (E.g. it is not denied execute despite the execute bit being set.) +,LockdownA,MmodeEnforce,"""[When mseccfg.MML is set.] An M-mode-only rule is enforced on Machine mode""","Be in M-mode, +have MML set, +access an ""M-mode-only"" region, +ensure that the grant/deny is always in accordance to the rule. +(E.g. it is not denied execute despite the execute bit being set.) -Note: Exclude cases of interference from e.g. PMA.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +Cover: grant / deny for this specific scenario. + +Note: Exclude cases of interference from e.g. PMA.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -COV: ???","(Same as for ""MmodeDeny"")" -,,UmodeDeny,"""[When mseccfg.MML is set.] An M-mode-only rule is [...] denied in Supervisor or User mode.""","Be in U-mode, have MML set, access an ""M-mode-only"" region, ensure that the access is always denied.",Assertion Check,Constrained-Random,Assertion Coverage,,A: ???,TODO missing assert -,,RemainLocked,"""It also remains locked so that any further modifications to its associated configuration or address registers are ignored until a PMP reset"" +COV: (SKIPPED)","(Same as for ""MmodeDeny"") -Certain rules under MML are sticky. They cannot be modified again.","Configure rules for {""M-mode-only"", ""U-mode-only, ""Shared-Region rule where pmpcfg.L is set""(both kinds)}, have MML=1 (and RLB=0), ensure that the configs never change again (until reset).",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: ??? +Cover skipped because assert is deemed sufficient." +,,UmodeDeny,"""[When mseccfg.MML is set.] An M-mode-only rule is [...] denied in Supervisor or User mode.""","Be in U-mode, +have MML set, +access an ""M-mode-only"" region, +ensure that the access is always denied.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: (SKIPPED),Explicit assert skipped in favor of model equivalence checking. +,,RemainLocked,"""[An M-mode-only rule] also remains locked so that any further modifications to its associated configuration or address registers are ignored until a PMP reset"" -COV: ???",TODO missing assert +Certain rules under MML are sticky. They cannot be modified again.","1) Configure for ""M-mode-only, +2) have MML=1 (and RLB=0), +3) ensure that the configs never change again (until reset). + +Cover: with mml=1. (Since the assert re-uses a different vplan item's assert.)",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: (See IgnoreWrites) + +COV: (SKIPPED)",Cover skipped because assert is deemed sufficient. ,,RlbUnlocks,"""It also remains locked [...] unless mseccfg.RLB is set.""","Have the same setup as in RemainLocked, but let RLB=1, try changing the configs, ensure that they are indeed changed. -Note: ""Assertion check"" includes cover properties.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: ??? +Note: ""Assertion check"" includes cover properties.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: (see ""ModifiableEntries"") -COV: ???",TODO missing assert -,,UmodeEnforce,"""[When mseccfg.MML is set.] An S/U-mode-only rule is enforced on Supervisor and User modes ""","Be in U-mode, have MML=1, access a ""U-mode-only"" region, ensure that the grant/deny is in accordance with the rule (apart from PMA etc).",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +COV: (See ""ModifiableEntries"")", +,,UmodeEnforce,"""[When mseccfg.MML is set.] An S/U-mode-only rule is enforced on Supervisor and User modes ""","1) Be in U-mode, +2) have MML=1, +3) access a ""U-mode-only"" region, +4) ensure that the grant/deny is in accordance with the rule (apart from PMA etc). + +Cover: Grant / deny.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_cp_data_side.cg_data COV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_cp_instr_side.cg_instr -COV: ???","(Same as for ""MmodeDeny"")" -,,MmodeDeny,"""An S/U-mode-only rule is [...] denied on Machine mode.""","Be in M-mode, have MML=1, access a ""U-mode-only"" region, ensure that the access is always denied.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +COV: (SKIPPED)","(Same as for ""MmodeDeny"") -COV: ???",TODO missing coverage. (Just do a cg with crosses of all of these variables.) -,,SharedEnforced,"""A Shared-Region rule is enforced on all modes""","Be in M-mode and U-mode (separate runs), access a ""Shared-Region"", ensure that the grant/deny is in accordance with the rule.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +Skipped cover for explicit deny, in favor of model equivalence checking." +,,MmodeDeny,"""An S/U-mode-only rule is [...] denied on Machine mode.""","1) Be in M-mode, +2) have MML=1, +3) access a ""U-mode-only"" region, +4) ensure that the access is always denied.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -COV: ???","(Same as for ""MmodeDeny"")" -,,SharedNoexec,"""A Shared-Region rule where pmpcfg.L is not set can be used for sharing data between M-mode and S/U-mode, so is not executable.""","Be in M-mode and U-mode, try to execute from ""A Shared-Region rule where pmpcfg.L is not set"", ensure that it does not work (exception).",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal + +COV: (SKIPPED)",Cover skipped in favor of model equivalence checking. +,,SharedEnforced,"""A Shared-Region rule is enforced on all modes""","1) Be in M-mode and U-mode (separate runs), +2) access a ""Shared-Region"", +3) ensure that the grant/deny is in accordance with the rule.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -COV: ???","(Same as for ""MmodeDeny"")" -,,MmodeReadwrite,"""[Shared-Region rule where pmpcfg.L is not set.] M-mode has read/write access to that region""","Be in M-mode, perform reads and writes to such a region, ensure that the intended effects happen and that the accesses do not cause exceptions.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal +COV: (See ""UmodeEnforce"").","(Same as for ""MmodeDeny"")" +,,SharedNoexec,"""A Shared-Region rule where pmpcfg.L is not set can be used for sharing data between M-mode and S/U-mode, so is not executable.""","1) Be in M-mode and U-mode, +2) try to execute from ""A Shared-Region rule where pmpcfg.L is not set"", +3) ensure that it does not work (exception).",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal + +COV: (See ""MmodeDeny"").","(Same as for ""MmodeDeny"")" +,,MmodeReadwrite,"""[Shared-Region rule where pmpcfg.L is not set.] M-mode has read/write access to that region""","1) Be in M-mode, +2) perform reads and writes to such a region, +3) ensure that the intended effects happen and that the accesses do not cause exceptions. + +Cover: read / write.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -COV: ???","(Same as for ""MmodeDeny"")" -,,UmodeRead,"""[For a Shared-Region rule where pmpcfg.L is not set] S/U-mode has read access if pmpcfg.X is not set, or read/write access if pmpcfg.X is set.""","Be in U-mode, perform reads and writes to such a region, ensure that the reads always work and that the writes depend on X.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal +COV: (See ""MmodeDeny"").","(Same as for ""MmodeDeny"")" +,,UmodeRead,"""[For a Shared-Region rule where pmpcfg.L is not set] S/U-mode has read access if pmpcfg.X is not set, or read/write access if pmpcfg.X is set.""","Be in U-mode, perform reads and writes to such a region, ensure that the reads always work and that the writes depend on X.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -COV: ???","(Same as for ""MmodeDeny"")" +COV: (See ""MmodeDeny"").","(Same as for ""MmodeDeny"")" ,,SharedNowrite,"""A Shared-Region rule where pmpcfg.L is set can be used for sharing code between M-mode and S/U-mode, so is not writeable."" -Note: The spec is unclear here, but ""A Shared-Region rule where pmpcfg.L is set"" must refer to ""LRWX=101X"", because ""The encoding pmpcfg.LRWX=1111"" is a separate point. (This holds for the subsequent items below too.)","Be in M-mode and U-mode, write to such a region, ensure that the writes do not reach the bus and that an exception occurs.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal +Note: The spec is unclear here, but ""A Shared-Region rule where pmpcfg.L is set"" must refer to ""LRWX=101X"", because ""The encoding pmpcfg.LRWX=1111"" is a separate point. (This holds for the subsequent items below too.)","Be in M-mode and U-mode, write to such a region, ensure that the writes do not reach the bus and that an exception occurs.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -COV: ???","(Same as for ""MmodeDeny"")" -,,BothExecute,"""Both M-mode and S/U-mode have execute access on the [Shared-Region rule where pmpcfg.L is set]""","Be in M-mode and U-mode, attempt to execute from such a region, ensure that the code is executed and that the attempt does not cause an exception.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal +COV: (See ""MmodeDeny"").","(Same as for ""MmodeDeny"")" +,,BothExecute,"""Both M-mode and S/U-mode have execute access on the [Shared-Region rule where pmpcfg.L is set]""","Be in M-mode and U-mode, attempt to execute from such a region, ensure that the code is executed and that the attempt does not cause an exception.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -COV: ???","(Same as for ""MmodeDeny"")" -,,MmodeRead,"""M-mode also has read access [to Shared-Region rule where pmpcfg.L is set] if pmpcfg.X is set.""","Be in M-mode, attempt to read from such a region, ensure that the success depends accordingly on X.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal +COV: (See ""MmodeDeny"").","(Same as for ""MmodeDeny"")" +,,MmodeRead,"""M-mode also has read access [to Shared-Region rule where pmpcfg.L is set] if pmpcfg.X is set.""","Be in M-mode, attempt to read from such a region, ensure that the success depends accordingly on X.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal -COV: ???","(Same as for ""MmodeDeny"")" -,,IgnoreUntilReset,"""The [Shared-Region rule where pmpcfg.L is set] remains locked so that any further modifications to its associated configuration or address registers are ignored until a PMP reset, unless mseccfg.RLB is set.""",(Covered by RemainLocked above.),Other,Other,N/A,,N/A, -,,BothReadonly,"""The encoding pmpcfg.LRWX=1111 can be used for sharing data between M-mode and S/U mode, where both modes only have read-only access to the region.""","Be in M-mode and U-mode, access such a region, ensure that only the reads work and that the rest (write/execute) excepts.",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal +COV: (See ""MmodeDeny"").","(Same as for ""MmodeDeny"")" +,,IgnoreUntilReset,"""The [Shared-Region rule where pmpcfg.L is set] remains locked so that any further modifications to its associated configuration or address registers are ignored until a PMP reset, unless mseccfg.RLB is set.""",(Covered by RemainLocked above.),Other,Other,N/A,High Priority,N/A, +,,BothReadonly,"""The encoding pmpcfg.LRWX=1111 can be used for sharing data between M-mode and S/U mode, where both modes only have read-only access to the region.""","Be in M-mode and U-mode, access such a region, ensure that only the reads work and that the rest (write/execute) excepts.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal + +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal COV: dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_cp_instr_side.cover_item_covergroup_cg_internals_instr_side_inst_cg_instr_coverpoint_cp_r_mmode_mml_lrwx @@ -353,8 +489,8 @@ COV: dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_ COV: dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_cp_data_side.cover_item_covergroup_cg_internals_data_side_inst_cg_instr_coverpoint_cp_r_umode_mml_lrwx -COV: ???","TODO technically missing the ""the rest … excepts"" cover" -,,ReadonlyLocked,"""The [pmpcfg.LRWX=1111] rule remains locked so that any further modifications to its associated configuration or address registers are ignored until a PMP reset, unless mseccfg.RLB is set.""",(Covered by RemainLocked above.),Other,Other,N/A,,N/A, +COV: (SKIPPED)","Non-exhaustive covers, in favor of model equivalence checking (technically missing the ""the rest … excepts"" cover)." +,,ReadonlyLocked,"""The [pmpcfg.LRWX=1111] rule remains locked so that any further modifications to its associated configuration or address registers are ignored until a PMP reset, unless mseccfg.RLB is set.""",(Covered by RemainLocked above.),Other,Other,N/A,High Priority,N/A, ,LegalRwx,,"Depending on the mseccfg control bits and L, some RWX combinations are reserved. Note: Use the table from the spec.",Ensure that illegal/reserved mseccfg/L/RWX combinations are unreachable.,Assertion Check,"ENV capability, not specific test",Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfg_expected[*].a_cfg_expected @@ -362,42 +498,48 @@ Note: Use the table from the spec.",Ensure that illegal/reserved mseccfg/L/RWX c A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgwdata_legal[*].a_cfgwdata_legal A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgrdata_expected[*].a_cfgrdata_expected", -,Reachable,,"All legal states in the table are reachable. It could theoretically be that platform-specific constraints made certain states unreachable (particularily related to locking), but we should be able to reach all legal and supported combinations of settings.",Ensure that all legal states are reachable.,Other,Constrained-Random,Functional Coverage,,COV: ???,TODO missing cover -manual,Parameters,MinimumGranularity,"""The PMP_GRANULARITY parameter is used to configure the minimum granularity of PMP address matching. The minimum granularity is [2^(PMP_GRANULARITY+2)] bytes, so at least 4 bytes.""","Have runs with max granularity, minimum granularity, and something in between. Make sure all checkers/covers are active for each relevant run configuration, so tor/napot/na4 is tested with different granularities. Cover cases where a match would otherwise occur but the granularity made the access not match. +,Reachable,,"All legal states in the table are reachable. It could theoretically be that platform-specific constraints made certain states unreachable (particularily related to locking), but we should be able to reach all legal and supported combinations of settings.",Ensure that all legal states are reachable.,Other,Constrained-Random,Functional Coverage,No,"COV: uvmt_cv32e40s_pmp_assert.sv, ""cg_internals_*"". -Note: Ensure TorMatching etc above heed this parameter.",Other,Constrained-Random,Functional Coverage,,COV: ???,TODO missing cover +COV: (SKIPPED)","Cover skipped for all explicit variations of ""denied"", in favor of model equivalence checking." +manual,Parameters,MinimumGranularity,"""The PMP_GRANULARITY parameter is used to configure the minimum granularity of PMP address matching. The minimum granularity is [2^(PMP_GRANULARITY+2)] bytes, so at least 4 bytes.""","Have runs with max granularity, minimum granularity, and something in between. Make sure all checkers/covers are active for each relevant run configuration, so tor/napot/na4 is tested with different granularities. + +Cover: cases where a match would otherwise occur but the granularity made the access not match. + +Note: Ensure TorMatching etc above heed this parameter.",Other,Constrained-Random,Functional Coverage,No,COV: (SKIPPED),Cover skipped in favor of release-specific configs and the rest of the tests/asserts. ,,NumRegions,"""The PMP_NUM_REGIONS parameter is used to configure the number of PMP regions, starting from the lowest numbered region."" -Note: Including 0 regions.","Have runs with max number, minimum number, and something in between.",Other,Constrained-Random,Functional Coverage,,COV: ???,TODO missing cover +Note: Including 0 regions.","Have runs with max number, minimum number, and something in between.",Other,Constrained-Random,Functional Coverage,No,COV: (SKIPPED),Cover skipped in favor of release-specific configs. ,,ResetValues,"""The reset value of the PMP CSR registers can be set through the top level parameters PMP_PMPNCFG_RV[], PMP_PMPADDR_RV[] and PMP_MSECCFG_RV.""","Have runs with different reset values. Ensure that after reset then the reset values are effectuated. -Note: Try also, reset values with locked configs.",Assertion Check,"ENV capability, not specific test",Functional Coverage,High Priority,"A: ??? - -COV: ???","TODO missing assert +Note: Try also, reset values with locked configs.",Assertion Check,"ENV capability, not specific test",Functional Coverage,No,"A: (SKIPPED) -TODO missing cover" -,,DefaultValues,The reset value defaults should amount to a safe config. (Including no violation of reserved bits.),(Covered by all the checks that handles the various legalities.),Other,Other,N/A,,N/A, +COV: (SKIPPED)",Assert and cover skipped in favor of release-specific configs and integration-level testing. +,,DefaultValues,The reset value defaults should amount to a safe config. (Including no violation of reserved bits.),(Covered by all the checks that handles the various legalities.),Other,Other,N/A,No,N/A, ,CSRs,AlwaysAccessible,"""All PMP CSRs are always implemented"". ""MRW"". The CSRs are M-mode accessible, and their existence does not depend on PMP_NUM_REGIONS. -Note: ""All"" pmp registers, and all fields within them.","Be in M-mode, access (reads/writes) all the pmp csrs, ensure that it always works without excepting (because the csrs exist and the mode is appropriate). +Note: ""All"" pmp registers, and all fields within them.","1) Be in M-mode, +2) access (reads/writes) all the pmp csrs, +3) ensure that it always works without excepting (because the csrs exist and the mode is appropriate). -Note: Potential overlap with CSR vplan.",Assertion Check,Directed Non-Self-Checking,Assertion Coverage,High Priority,A: ???,TODO missing assert -,,ReservedLegal,"Reserved bits/fields have legal values, matching the platform-specified defaults.","(Overlaps with LegalRwx and RwReservedabove.) Read all fields of all pmp-related csrs, ensure there are no unsupported values anywhere (at all times).",Assertion Check,Constrained-Random,Assertion Coverage,,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgrdata_expected[*].a_cfgrdata_expected, -,,MseccfghZero,"""Hardwired to 0""","Read mseccfgh, ensure it is always 0.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: ???,TODO missing assert +Note: Potential overlap with CSR vplan.",Assertion Check,Directed Non-Self-Checking,Assertion Coverage,No,"A: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_always_accessible_mmode_csrs"".", +,,ReservedLegal,"Reserved bits/fields have legal values, matching the platform-specified defaults.","(Overlaps with LegalRwx and RwReservedabove.) +Read all fields of all pmp-related csrs, ensure there are no unsupported values anywhere (at all times).",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgrdata_expected[*].a_cfgrdata_expected, +,,MseccfghZero,"""Hardwired to 0""","Read mseccfgh, ensure it is always 0.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,"A: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_mseccfgh_zero"".", ,,UnusedZero,"""CSRs (or bitfields of CSRs) related to PMP entries with number PMP_NUM_REGIONS and above are hardwired to zero."" -Note: Including upper parts of pmpcfgn and also pmpaddr.","Read pmpcfg and pmpaddr csrs, ensure the values are zero as specified. Cover that the other values can be non-zero.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: ??? +Note: Including upper parts of pmpcfgn and also pmpaddr.","1) Read pmpcfg and pmpaddr csrs, +2) ensure the values are zero as specified. -COV: ???","TODO missing assert +Cover: that the other values can be non-zero.",Assertion Check,Constrained-Random,Functional Coverage,No,"A: uvmt_cv32e40s_pmp_assert.sv, ""a_unused_zero_pmp_csrs"". -TODO missing cover" -,,Hardening,"Certain CSRs related to the PMP shall be ""hardened"" as per Xsecure.","(CSR hardening is the responsibility of the security features vplan, even the pmp-specific part of it.)",N/A,N/A,N/A,,N/A, +COV: (SKIPPED).",Cover skipped as not important. +,,Hardening,"Certain CSRs related to the PMP shall be ""hardened"" as per Xsecure.","(CSR hardening is the responsibility of the security features vplan, even the pmp-specific part of it.)",N/A,N/A,N/A,High Priority,N/A, ,MicroArchitecture,WaitUpdate,"Updates to pmp configs should NOT have an effect on earlier instructions (nor on the instruction itself). Note: Potential security hole.","The pmp grant/deny checking must be compared vs ""rvfi_csr__rdata"". (This will detect whether the actual pmp decision differs from what the rvfi csr data would incidate.) -Note: Compare ""pc_rdata"" for execute, and ""mem_"" signals for read/write. (Might need additional decoding of ""rvfi_insn"".)",Assertion Check,"ENV capability, not specific test",Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_musttrap +Note: Compare ""pc_rdata"" for execute, and ""mem_"" signals for read/write. (Might need additional decoding of ""rvfi_insn"".)",Assertion Check,"ENV capability, not specific test",Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_musttrap A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_load @@ -409,10 +551,8 @@ A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_cause -A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_splittrap - -COV: ???",TODO missing cover -,,,,"Inject pmp csr write instructions in random testing, intermingled with all other kinds of instructions. This should include random interrupts, bus faults, random bus stalls, etc.",Check against RM,Constrained-Random,Functional Coverage,,COV: ???,TODO missing cover +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_splittrap", +,,,,"Inject pmp csr write instructions in random testing, intermingled with all other kinds of instructions. This should include random interrupts, bus faults, random bus stalls, etc.",Check against RM,Constrained-Random,Functional Coverage,No,COV: (SKIPPED),Cover skipped because random testing of pmp proved to be low ROI. ,,AffectSuccessors,"Updates to pmp configs MUST have an effect on later instructions. Note: Potential security hole. @@ -423,100 +563,131 @@ Note: There was a known rtl bug here before (cv32e40s/issues/168).","The ""rvfi_ A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_rvfi_csr_writes[0].a_rvfi_cfg_writes A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_rvfi_csr_writes[0].a_rvfi_addr_writes", -,,,,(Same random testing as WaitUpdate above.),Other,Other,N/A,,N/A, -,,ImplementationDetails,"Details about pipeline/prefetcher/bus flushing etc are not part of this vplan. Only black-box observable functional behavior is checked. (Such requirements exists in specs, but are deliberately not addressed here.)",N/A,N/A,N/A,N/A,,N/A, -,,Performance,Requirements about performance and stalls etc are not covered here (unless review calls for the opposite).,N/A,N/A,N/A,N/A,,N/A, -,,WriteBuffer,Changes to the pmp config should not impact the write buffer such that a transaction can get its grant/deny status altered.,"Cover cases of the write buffer being full while the pmp cfg changes. Checking of accidental grants is handled by SuppressReq below. Checking of guaranteed writes is not part of this vplan. +,,,,(Same random testing as WaitUpdate above.),Other,Other,N/A,No,N/A, +,,ImplementationDetails,"Details about pipeline/prefetcher/bus flushing etc are not part of this vplan. Only black-box observable functional behavior is checked. (Such requirements exists in specs, but are deliberately not addressed here.)",N/A,N/A,N/A,N/A,No,N/A, +,,Performance,Requirements about performance and stalls etc are not covered here (unless review calls for the opposite).,N/A,N/A,N/A,N/A,No,N/A, +,,WriteBuffer,Changes to the pmp config should not impact the write buffer such that a transaction can get its grant/deny status altered.,"Cover cases of the write buffer being full while the pmp cfg changes. Checking of accidental grants is handled by SuppressReq below. +Checking of guaranteed writes is not part of this vplan. -Note: The Write buffer is situated between the pmp and the bus.",Other,Other,Functional Coverage,High Priority,COV: ???,TODO missing cover +Note: The Write buffer is situated between the pmp and the bus.",Other,Other,Functional Coverage,High Priority,"COV: (See ""WaitUpdate"").", ,Violations,SuppressReq,"When an access is denied by the pmp, the effect is that the attempted obi transaction is suppressed and does not reach the bus. Note: Both ""instr_req_o"" and ""data_req_o"".","Observe a transaction request coming in to the pmp module, observe the pmp denying the access, ensure that the obi bus is shielded from the transaction request.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_supress_req_data.a_suppress_req_data A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_supress_req_instr.a_suppress_req_instr", -,,InternalBuses,(The transaction request feeding into the mpu and its response signaling is not covered by this vplan.),N/A,N/A,N/A,N/A,,N/A, +,,InternalBuses,(The transaction request feeding into the mpu and its response signaling is not covered by this vplan.),N/A,N/A,N/A,N/A,No,N/A, ,,ExceptionExecute,"""mcause [...] Instruction access fault [...] Execution attempt with address failing PMP check.""","Attempt execution of a region that pmp denies execution of, ensure that an ""instruction access fault"" exception occurs (read mcause and rvfi signals). -Note: Since ISS can check most of this, one could deprioritize this checking if it is not feasible to check within reasonable efforts. (Same for the next 2 items.)",Assertion Check,Constrained-Random,Assertion Coverage,,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_cause, +Note: Since ISS can check most of this, one could deprioritize this checking if it is not feasible to check within reasonable efforts. (Same for the next 2 items.)",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_cause, ,,ExceptionLoad,"""mcause [...] Load access fault [...] Load attempt with address failing PMP check."" -Note: Holds for load-reserved too.","Attempt loads (and load-reserveds) of a region that pmp denies reading from, ensure that a ""load access fault"" exception occurs (read mcause and rvfi signals).",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_load +Note: Holds for load-reserved too.","1) Attempt loads (and load-reserveds) of a region that pmp denies reading from, +2) ensure that a ""load access fault"" exception occurs (read mcause and rvfi signals). + +Cover: normal / load-reserved / pop.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_load -COV: ???",TODO missing cover +COV: (SKIPPED).","Cover skipped as ""rvfi_if.is_load_instr"" should handle all load types." ,,ExceptionStore,"""mcause [...] Store/AMO access fault [...] Store attempt with address failing PMP check."" -Note: Holds for store-conditional and amo too.","Attempt stores (and store-conditionals and amo) to a region that pmp denies writing to, ensure that a ""store/amo access fault"" exception occurs (read mcause and rvfi signals).",Assertion Check,Constrained-Random,Functional Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_store +Note: Holds for store-conditional and amo too.","1) Attempt stores (and store-conditionals and amo) to a region that pmp denies writing to, +2) ensure that a ""store/amo access fault"" exception occurs (read mcause and rvfi signals).",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_store -COV: ???",TODO missing cover +COV: (SKIPPED).","Cover skipped as ""rvfi_if.is_store_instr"" should handle all store types." ,,TrapPrecisely,"""All exceptions are precise"". Meaning mepc will point to the offending instruction, and exactly previous instructions have their side effects fully visible. Note: Applies to loads, stores, and executes.","Observe that the pmp causes an exception, ensure that mepc points to the offending instruction. -Note: Let the Exceptions vplan deal with visibility of side effects for earlier instructions. (Zc push/pop does not follow this, but that is mostly the responsibility of the Zc vplan.) +Note: Let the Exceptions vplan deal with visibility of side effects for earlier instructions. +(Zc push/pop does not follow this, but that is mostly the responsibility of the Zc vplan.) -Note: If satisfactory mepc checking already exist then it is acceptable to just add covers for the pmp scenarios.",Assertion Check,Constrained-Random,Functional Coverage,,"A: ??? +Note: If satisfactory mepc checking already exist then it is acceptable to just add covers for the pmp scenarios.",Assertion Check,Constrained-Random,Functional Coverage,No,"A: (SKIPPED). -COV: ???","TODO missing assert +COV: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_noexec_cause"". -TODO missing cover" -,,AlertMinor,"""The following issues result in a minor security alert: [...] Instruction access fault [...] Load access fault [...] Store/AMO access fault""",(Responsibility of the xsecure vplan. But link to coverage here too.),N/A,N/A,N/A,,"A: ??? +COV: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_noloadstore_cause_load"". -COV: ???",Waiting for xsecure vplan +COV: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_noloadstore_cause_store"".","Assertion skipped because 1) we don't have readily-available helper signals for non-clic pointers, and 2) this is not a high priority assert. (It could be easy to write and assert that mepc is pc_rdata, with some exceptions to that rule.)" +,,AlertMinor,"""The following issues result in a minor security alert: [...] Instruction access fault [...] Load access fault [...] Store/AMO access fault""",(Responsibility of the xsecure vplan. But link to coverage here too.),N/A,N/A,N/A,High Priority,"A: uvmt_cv32e40s_xsecure_security_alerts_assert.sv, ""a_xsecure_security_alert_non_nmi_exceptions"". + +COV: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_noexec_cause"". + +COV: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_noloadstore_cause_load"". + +COV: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_noloadstore_cause_store"".",Waiting for xsecure vplan ,,AlertNothing,"The manual lists which pmp-related events can cause an alert minor, but the pmp should in no other cases be the cause for an alert (major/minor). Note: Example, ""attempt to reprogram a locked PMP""","Observe an alert signal going high while there is no pmp error that should have caused it, ensure that another viable reason for the alert was present. -Note: This is slightly out of scope for this vplan, so if it is not very easy to hook on to existing xsecure (helper-)signals then this can be skipped.",Assertion Check,Constrained-Random,Assertion Coverage,,A: ???,TODO missing assert -,,SplitLoadRegfile,"Even if parts of a split load can reach the bus, the instruction itself has failed and so the regfile should not get updated.","(Handled by ""SplitLoadException"" below, because: One only needs to show that an exception is caused, and the exceptions vplan is responsible for checking what that means for the regfile. (But link to coverage here too.))",N/A,N/A,N/A,,A: ???,Waiting for exceptions vplan -,,SplitLoadException,"For split loads, regardless of which of the access that fails, the instruction should still cause an exception.","Perform a misaligned load that translates to multiple accesses, let any of the accesses be denied by pmp, ensure an exception occurs. +Note: This is slightly out of scope for this vplan, so if it is not very easy to hook on to existing xsecure (helper-)signals then this can be skipped.",Assertion Check,Constrained-Random,Assertion Coverage,No,A: (SKIPPED).,Assert skipped in favor of deeming the xsecure verification and integration-level testing sufficient. +,,SplitLoadRegfile,"Even if parts of a split load can reach the bus, the instruction itself has failed and so the regfile should not get updated.","(Handled by ""SplitLoadException"" below, because: One only needs to show that an exception is caused, and the exceptions vplan is responsible for checking what that means for the regfile. (But link to coverage here too.))",N/A,N/A,N/A,No,"A: uvmt_cv32e40s_rvfi_assert.sv, ""a_exceptions_dont_update_gprs"".", +,,SplitLoadException,"For split loads, regardless of which of the access that fails, the instruction should still cause an exception.","1) Perform a misaligned load that translates to multiple accesses, +2) let any of the accesses be denied by pmp, +3) ensure an exception occurs. -Coverage: See rvfi retire with exception cause from pmp, while the ""low addr"" model checking gave access granted.",Assertion Check,Constrained-Random,Functional Coverage,,"A: ??? +Coverage: See rvfi retire with exception cause from pmp, while the ""low addr"" model checking gave access granted.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,"A: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_noloadstore_splittrap"".","Note: The assert only checks that the 2nd access is denied, not the general case of _any_." +,,FirstFail,"If a split load/store fails on its first transaction it should get an exception immediately, so it should not allow the second transaction reach the bus and mcause shall reflect the failing transactions.","1 Attempt such an instruction, +2) ensure that the denied access does not reach the bus, +3) ensure that following accesses also do not reach the bus. -COV: ???","TODO missing assert +Cover: load / store.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,"A: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_rvfi_mem_allowed_data"". -TODO missing cover" -,,FirstFail,"If a split load/store fails on its first transaction it should get an exception immediately, so it should not allow the second transaction reach the bus and mcause shall reflect the failing transactions.","Attempt such an instruction, ensure that the denied access does not reach the bus, ensure that following accesses also do not reach the bus.",Assertion Check,Constrained-Random,Assertion Coverage,,A: ???,TODO missing assert +A: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_rvfi_mem_allowed_upperdata"".",Note: Trusting RVFI to report OBI actuals truthfully. ,,PushPop,"If a push/pop fails on a transaction it should get an exception immediately, so the remaining transactions should not reach the bus and mcause shall reflect the failing transaction.","(Responsibility of the zc vplan. But link to coverage here too.) -Note: Could write a pmp-specific cover, but coordinate with Zc vplan to ensure the checker is written too.",N/A,N/A,N/A,,"A: ??? +Cover: could write a pmp-specific cover, but coordinate with Zc vplan to ensure the checker is written too.",N/A,N/A,N/A,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.u_zc_assert.a_multiop_exception_stop_dbus_push -COV: ???",Waiting for zc vplan +A: A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.u_zc_assert.a_multiop_exception_stop_dbus_pop + +COV: (SKIPPED).",Cover skipped in favor of trusting that formal will exercise the assert for pmp-specific cases. ,,TableJump,PMP applies to table jumps and Zc instructions in general.,"(Responsibility of the zc vplan. But link to coverage here too.) -Note: Could write a pmp-specific cover, but coordinate with Zc vplan to ensure the checker is written too.",N/A,N/A,N/A,,"A: ??? +Note: Could write a pmp-specific cover, but coordinate with Zc vplan to ensure the checker is written too.",N/A,N/A,N/A,High Priority,"A: (SKIPPED). -COV: ???",Waiting for zc vplan -,,ClicVector,"Similarly to TableJump above, CLIC vector fetch needs execute permission.",(Analogous to TableJump above.),N/A,N/A,N/A,,"A: ??? +COV: (SKIPPED).",Assert and cover skipped in favor of trusting that formal will exercise the assert for pmp-specific cases. +,,ClicVector,"Similarly to TableJump above, CLIC vector fetch needs execute permission.",(Analogous to TableJump above.),N/A,N/A,N/A,High Priority,"A: ??? -COV: ???",Waiting for clic vplan +COV: ???",TODO Waiting for clic vplan ,,Priority,"Exceptions priority apply to the PMP as well. Particularily, PMP exception (instruction access fault) gets priority over bus errors (instruction bus fault) if an instruction is the result of two fetches were both of these occurred. -Note: Both could be present in an attempted executed instruction at the same time, because no exception occurs before the point of execution so there is enough time for both to be captured and travel through the pipeline.","Keep track of words fetched with bus error and with pmp execute denied, check retired instructions for a pc that overlaps two such fetches (cover both orders), ensure that ""instruction access fault"" is the taken exception.",Assertion Check,Constrained-Random,Functional Coverage,,"A: ??? +Note: Both could be present in an attempted executed instruction at the same time, because no exception occurs before the point of execution so there is enough time for both to be captured and travel through the pipeline.","1) Keep track of words fetched with bus error and with pmp execute denied, +2) check retired instructions for a pc that overlaps two such fetches (cover both orders), +3) ensure that ""instruction access fault"" is the taken exception.",Assertion Check,Constrained-Random,Functional Coverage,No,"A: (SKIPPED). + +COV: (SKIPPED).","Assert and cover skipped because it would require support logic with an unreasonably low ROI, and we have other exceptions checking." +,Pma,RevokeExecutable,"Even if the pma should allow for execution, the pmp can overrule it and deny access.","Set up pma and pmp regions such that both have rules covering the same addresses, let the pma allow for execution, let the pmp deny it, attempt execution, ensure that execution is indeed denied.",Assertion Check,Constrained-Random,Assertion Coverage,No,A: (SKIPPED).,Assert skipped in favor of regarding the pmp and pma efforts themselves as sufficient. +,,RemainNonexecutable,"If the pma disallows execution, the pmp cannot change this fact and execution remains disallowed.","Set up pma and pmp regions such that both have rules covering the same addresses, let the pma disallow execution, let the pmp allow and deny execution (separate runs), attempt execution, ensure that execution is denied.",Assertion Check,Constrained-Random,Assertion Coverage,No,A: (SKIPPED).,Assert skipped in favor of regarding the pmp and pma efforts themselves as sufficient. +,,RevokePermissible,"Even if the pma allows for data access, the pmp can overrule it and deny access.","Set up pma and pmp regions such that both have rules covering the same addresses, let the pma allow for read and write (separate or same runs), let pmp deny read/write, attempt read/write, ensure that the pmp can overrule the pma.",Assertion Check,Constrained-Random,Assertion Coverage,No,A: (SKIPPED).,Assert skipped in favor of regarding the pmp and pma efforts themselves as sufficient. +,,RemainNonpermissible,"If the pma disallows data access, the pmp cannot change this fact and data access remains disallowed.","Set up pma and pmp regions such that both have rules covering the same addresses, let the pma deny read and write, let pmp allow or deny it, attempt read/write, ensure that the access is always denied.",Assertion Check,Constrained-Random,Assertion Coverage,No,A: (SKIPPED).,Assert skipped in favor of regarding the pmp and pma efforts themselves as sufficient. +,,DisallowDebug,"""As execution based debug is used, the Debug Module region, as defined by the DM_REGION_START and DM_REGION_END parameters, needs to support code execution, loads and stores when CV32E40S is in debug mode. In order to achieve this CV32E40S overrules the PMA and PMP settings for the Debug Module region when it is in debug mode (see Physical Memory Attribution (PMA) and Physical Memory Protection (PMP)).""","Check that accesses to the DM region are never blocked. -COV: ???","TODO missing assert +Cover: access within range, would deny / allow.",Assertion Check,Directed Non-Self-Checking,Assertion Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal -TODO missing cover" -,Pma,RevokeExecutable,"Even if the pma should allow for execution, the pmp can overrule it and deny access.","Set up pma and pmp regions such that both have rules covering the same addresses, let the pma allow for execution, let the pmp deny it, attempt execution, ensure that execution is indeed denied.",Assertion Check,Constrained-Random,Assertion Coverage,,A: ???,TODO missing assert -,,RemainNonexecutable,"If the pma disallows execution, the pmp cannot change this fact and execution remains disallowed.","Set up pma and pmp regions such that both have rules covering the same addresses, let the pma disallow execution, let the pmp allow and deny execution (separate runs), attempt execution, ensure that execution is denied.",Assertion Check,Constrained-Random,Assertion Coverage,,A: ???,TODO missing assert -,,RevokePermissible,"Even if the pma allows for data access, the pmp can overrule it and deny access.","Set up pma and pmp regions such that both have rules covering the same addresses, let the pma allow for read and write (separate or same runs), let pmp deny read/write, attempt read/write, ensure that the pmp can overrule the pma.",Assertion Check,Constrained-Random,Assertion Coverage,,A: ???,TODO missing assert -,,RemainNonpermissible,"If the pma disallows data access, the pmp cannot change this fact and data access remains disallowed.","Set up pma and pmp regions such that both have rules covering the same addresses, let the pma deny read and write, let pmp allow or deny it, attempt read/write, ensure that the access is always denied.",Assertion Check,Constrained-Random,Assertion Coverage,,A: ???,TODO missing assert -misc,Misc,DisallowDebug,The PMP can deny usage of debug mode by setting up regions for dm_halt_addr and dm_exception_addr.,"Set up pmp rules so all D-mode entries are blocked from execution, attempt to enter debug mode, ensure that nohing is executed in debug mode.",Assertion Check,Directed Non-Self-Checking,Assertion Coverage,,A: ???,Waiting for ongoing spec changes to be resolved -,,40x,The 40x does not have PMP.,N/A,N/A,N/A,N/A,,N/A, -,,Xif,"The X-interface can do memory operations, but the 40x does not have PMP and the 40s does not have XIF.",N/A,N/A,N/A,N/A,,N/A, +A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal + +COV: (SKIPPED).",Cover skipped in favor of trusting that formal will exercise the assert for dm region specific cases. +misc,Misc,40x,The 40x does not have PMP.,N/A,N/A,N/A,N/A,No,N/A, +,,Xif,"The X-interface can do memory operations, but the 40x does not have PMP and the 40s does not have XIF.",N/A,N/A,N/A,N/A,No,N/A, ,,RvfiReliable,"Rvfi is used for checking some pmp functionality, so the link between rvfi and pmp must be checked.","If feasible to model within reasonable effort, check that 1) the PMPs' privmode inputs and 2) CSRs and 3) wdata/wmask is for csr write instrs, are properly correlated between access attempts and rvfi reportings. -Otherwise, leave this to general ISS checking.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_* +Otherwise, leave this to general ISS checking.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,No,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_* A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_* (Indirectly checked by those asserts)", -,,RvfiTrap,"The ""rvfi_trap"" table has PMP-specific fields.","Augment the exception checkers above with checking of ""rvfi_trap.cause_type"" to ensure that specifically PMP is reported as the cause.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,,A: ???,TODO missing assert +,,RvfiTrap,"The ""rvfi_trap"" table has PMP-specific fields.","Augment the exception checkers above with checking of ""rvfi_trap.cause_type"" to ensure that specifically PMP is reported as the cause. +E.g. ""|-> rvfi_trap"" changed to ""|-> rvfi_trap && "".",Assertion Check,"ENV capability, not specific test",Assertion Coverage,No,"A: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_noexec_cause"". + +A: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_noloadstore_cause_load"". + +A: uvmt_cv32e40s_pmprvfi_assert.sv, ""a_noloadstore_cause_store"".", ,,UntilReset,"Everything that can get locked ""until reset"" must be possible to change after a reset. It should not be possible that these settings lock up so even resets cannot unlock them. -Note: Formal's reset analysis should in principle be able to find every state that is possible to be in after a reset.","(Covered by ResetValues above. As long as those always take effect out of reset, then a permanent lock up should be either impossible or intentional.)",N/A,N/A,N/A,,N/A, -,,Xsecure,(Will be covered by its own vplan.),N/A,N/A,N/A,N/A,,N/A, -,,Reset,The PMP module is never reset without the whole core being reset. (As this could lift all the locks and stickies and grant privilege escalation.),Check that the core's reset is always equal to the pmp module's reset.,Assertion Check,"ENV capability, not specific test",Assertion Coverage,,A: ???,TODO missing assert -,,UmodeZeroRegions,"If the parameters are set to have 0 pmp regions, then all rules are OFF and U-mode matches nothing and defaults to not have any access.","Be in U-mode, have PMP_NUM_REGIONS=0, ensure all accesses fail (read/write/execute).",Assertion Check,Constrained-Random,Assertion Coverage,,A: ???,TODO missing assert +Note: Formal's reset analysis should in principle be able to find every state that is possible to be in after a reset.","(Covered by ResetValues above. As long as those always take effect out of reset, then a permanent lock up should be either impossible or intentional.)",N/A,N/A,N/A,No,N/A, +,,Xsecure,(Will be covered by its own vplan.),N/A,N/A,N/A,N/A,High Priority,N/A, +,,Reset,The PMP module is never reset without the whole core being reset. (As this could lift all the locks and stickies and grant privilege escalation.),Check that the core's reset is always equal to the pmp module's reset.,Assertion Check,"ENV capability, not specific test",Assertion Coverage,No,A: (SKIPPED).,"Skipped in favor of trusting ""WaitUpdate"" and ""AffectSuccessors"" and all other functional asserts.." +,,UmodeZeroRegions,"If the parameters are set to have 0 pmp regions, then all rules are OFF and U-mode matches nothing and defaults to not have any access.","Be in U-mode, have PMP_NUM_REGIONS=0, ensure all accesses fail (read/write/execute). + +Note: also assert that read/write attempts can not occur.",Assertion Check,Constrained-Random,Assertion Coverage,High Priority,A: (SKIPPED).,Skipped in favor of using realease-specific configs. debug,Mmode,,"""All operations are executed with machine mode privilege"". It is mostly the responsibility of other vplans to check D-mode relationship to M-mode and U-mode, but the pmp inputs should be checked against debug mode. @@ -524,19 +695,10 @@ Note: Refer to user-mode vplan and debug vplan if necessary. Note: It is assumed that once 1) dmode is shown to be interpreted as mmode by pmp, and 2) all mmode features are verified, then C) the mmode features will work in dmode. But one alternative is to duplicate all the mmode-related checking with dmode variants.","Ensure that the PMP inputs receive the correct mode while in D-mode. -Note: Test w/wo MPRV too.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_* +Cover: w/wo MPRV.",Assertion Check,Constrained-Random,Functional Coverage,High Priority,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_* A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_* (Indirectly checked by those asserts, together with effective priv mode and umode asserts for dmode/mmode.) -COV: ???",TODO missing cover -,,,,,,,,,, -,,,,,,,,,, -,,,,,,,,,, -,,,,,,,,,, -,,,,,,,,,, -,,,,,,,,,, -,,,,,,,,,, -,,,,,,,,,, - -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- END -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------,,,,,,,,,, +COV: (SKIPPED).","Cover skipped because the asserts are deemed sufficient, and because debug has its own new override mechanism." diff --git a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.json b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.json index 43080652d0..d7dc326a6f 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.json +++ b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.json @@ -1,14 +1,14 @@ [ { - "Requirement Location": "", + "Requirement Location": "N/A", "Feature": "Comments", "Sub Feature": "SmepmpOverrule", - "Feature Description": "The \"smepmp\" spec features can overrule the \"privspec\" (e.g. for locking). Both specs are included here, so be mindful that checking of certain vplan items could be conditional.", + "Feature Description": "\"smepmp\" features can overrule the \"privspec\" (e.g. locking). Both specs are included here, so be aware that certain vplan items are conditional.", "Verification Goal": "N/A", "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -16,12 +16,12 @@ "Requirement Location": "", "Feature": "Comments", "Sub Feature": "FunctionalCoverage", - "Feature Description": "Functional coverage is encouraged to be creative in capturing a broad set of possible state, and evaluate it towards the checkers, to catch aspects of pmp functionality that this vplan might have overlooked.", + "Feature Description": "Functional coverage should capture a broad set of possible state (could be compared with the checkers), to find crosses that this vplan might have overlooked.", "Verification Goal": "N/A", "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -29,12 +29,12 @@ "Requirement Location": "", "Feature": "Comments", "Sub Feature": "ImplementationChanges", - "Feature Description": "If test implementation reveals new knowledge that contradicts or augments this vplan, then the vplan should be updated.", + "Feature Description": "If test implementation gains new knowledge, then update this vplan when appropriate.", "Verification Goal": "N/A", "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -42,12 +42,12 @@ "Requirement Location": "", "Feature": "Comments", "Sub Feature": "TimeAllowance", - "Feature Description": "Some verification goals in this plan has a \"base level\" of checking plus some optional tweaks that might be tried. It is up to the testing implementation how to prioritize and potentially skip the extras, according to what time allows.", + "Feature Description": "Some of the verification goals have a \"base level\" of checking plus optional tweaks. It is up to implementation to prioritize and potentially skip the extras.", "Verification Goal": "N/A", "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -56,13 +56,13 @@ "Feature": "General", "Sub Feature": "Configs", "Feature Description": "The pmp must be tested in a wide range of configurations. That includes testing on both instruction-side and data-side, and it includes testing overlapping regions, non-overlaping, no regions, differing settings for overlapping regions, M-mode only, U-mode only, both M-mode and U-mode, etc, etc. Use functional coverage with plenty of crosses.", - "Verification Goal": "Run with different configs to test parameters in low/mid/high ranges and in combination with the other parameters, instantiate checking on both instruction-side and data-side, write coverage to see all relevant region overlap combinations and to see an exhaustive combination of block-level input combinations and functional-level states.", + "Verification Goal": "Run with different configs to test parameters in low/mid/high ranges and in combination with the other parameters, instantiate checking on both instruction-side and data-side.\n\nCover: see all relevant region overlap combinations and to see an exhaustive combination of block-level input combinations and functional-level states.", "Pass/Fail Criteria": "Other", "Test Type": "ENV capability, not specific test", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "COV: ???", - "Comment": "TODO missing cover" + "High Priority?": "No", + "Link to Coverage": "COV: (SKIPPED)", + "Comment": "Skipped in favor of using realease-specific configs." }, { "Requirement Location": "", @@ -73,35 +73,35 @@ "Pass/Fail Criteria": "Other", "Test Type": "Other", "Coverage Method": "N/A", - "High Priority?": "", - "Link to Coverage": "N/A", - "Comment": "" + "High Priority?": "No", + "Link to Coverage": "(SKIPPED)", + "Comment": "Skipped in favor of considering the normal assertions good enough and using release-specific configs." }, { "Requirement Location": "", "Feature": "General", "Sub Feature": "UmodeAlways", "Feature Description": "\"PMP checks are applied to all accesses whose effective privilege mode is S or U, including instruction fetches in S and U mode, data accesses in S and U mode when the MPRV bit in the mstatus register is clear, and data accesses in any mode when the MPRV bit in mstatus is set and the MPP field in mstatus contains S or U.\"\n\nNote: None of those scenarios should let an access bypass the pmp.", - "Verification Goal": "Set up the system to match each point in the listing, ensure that the pmp's decision matches all modelled expectations.\n\nNote: Also cover when none of the listed preconditions are active and the pmp's decision can disagree with the modelled expectations.", + "Verification Goal": "Set up the system to match each point in the listing, ensure that the pmp's decision matches all modelled expectations.\n\nCover: when none of the listed preconditions are active and the pmp's decision can disagree with the modelled expectations.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_*\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_*\n\nCOV: ???", - "Comment": "(Same as for \"MmodeDeny\")" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_*\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_*\n\nCOV: (SKIPPED)", + "Comment": "(Same as for \"MmodeDeny\")\n\nCover is skipped because it is not essential, and we have equivalence checking of RTL vs model." }, { "Requirement Location": "", "Feature": "General", "Sub Feature": "DefaultNone", "Feature Description": "\"PMP can grant permissions to S and U modes, which by default have none\"", - "Verification Goal": "Check that, out of reset, given no extraordinary reset values, and given no change to the pmp csrs, then U-mode has no access permissions.", + "Verification Goal": "Given:\n1) out of reset,\n2) no extraordinary reset values,\n3) no change to the pmp csrs.\n\nThen:\nU-mode has no access permissions. (I.e. always excepts.)", "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nDTC: cv32e40s/tests/programs/custom/pmp/", - "Comment": "TODO missing assert" + "High Priority?": "High Priority", + "Link to Coverage": "A: (SKIPPED).\n\nDTC: cv32e40s/tests/programs/custom/pmp/", + "Comment": "Skipped in favor of using realease-specific configs (which have \"extraordinary reset values\")." }, { "Requirement Location": "", @@ -112,9 +112,9 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nDTC: cv32e40s/tests/programs/custom/pmp/", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED)\n\nDTC: cv32e40s/tests/programs/custom/pmp/", + "Comment": "Skipped in favor of the directed test and the entire test suite in general." }, { "Requirement Location": "", @@ -125,100 +125,100 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nDTC: cv32e40s/tests/programs/custom/pmp/", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED)\n\nDTC: cv32e40s/tests/programs/custom/pmp/", + "Comment": "Skipped in favor of integration-level testing w/ release-specific configs, and the directed test." }, { "Requirement Location": "", "Feature": "Csrs", "Sub Feature": "Warl", "Feature Description": "\"All PMP CSR fields are WARL and may be hardwired to zero\".\n\nNote: A field shall also not change its value when an attempt is made to write an illegal value to it. (XWR is one field.)", - "Verification Goal": "Try writing any values to the registers and read values out of them, ensure that neither reads nor writes causes exceptions, and ensure that all read values are legal or otherwise as expected and that illegally written fields don't change.", + "Verification Goal": "Try writing any values to the registers and read values out of them.\nEnsure that neither reads nor writes causes exceptions.\nAnd ensure that all read values are legal or otherwise as expected and that illegally written fields don't change.\n\nCover: access to all CSRs and all fields.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfg_expected[*].a_cfg_expected\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgwdata_legal[*].a_cfgwdata_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgrdata_expected[*].a_cfgrdata_expected\n\nCOV: ???", - "Comment": "TODO missing cover" + "High Priority?": "No", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfg_expected[*].a_cfg_expected\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgwdata_legal[*].a_cfgwdata_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgrdata_expected[*].a_cfgrdata_expected\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped because the asserts are deemed sufficient." }, { "Requirement Location": "", "Feature": "Csrs", "Sub Feature": "MmodeOnly", "Feature Description": "\"PMP CSRs are only accessible to M-mode.\"", - "Verification Goal": "Try to access any of the pmp CSRs from U-mode, ensure that it always gives \"illegal instruction exception\" and that the CSRs are not updated.\n\nNote: M-mode accesses are covered by AlwaysAccessible below.", + "Verification Goal": "Try to access any of the pmp CSRs from U-mode, ensure that it always gives \"illegal instruction exception\" and that the CSRs are not updated.\n\nCover: For all CSRs.\n\nNote: M-mode accesses are covered by AlwaysAccessible below.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_csrs_mmode_only\n\nCOV: ???\n\nDTC: cv32e40s/tests/programs/custom/pmp/", - "Comment": "TODO missing cover (combine with \"Warl\" above)" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_csrs_mmode_only\n\nCOV: (SKIPPED)\n\nDTC: cv32e40s/tests/programs/custom/pmp/", + "Comment": "Cover skipped because the asserts and directed test are deemed sufficient." }, { "Requirement Location": "", "Feature": "Csrs", "Sub Feature": "Addr34bit", "Feature Description": "\"Each PMP address register encodes bits 33\u20132 of a 34-bit physical address for RV32\"", - "Verification Goal": "Ensure that when the pmpaddr MSBs are set, then no NAPOT accesses matches. Cover that all bits have been matched against (\"toggle cross\"). Ensure that there are no attempted accesses to MSBs that the core should not be able to use.", + "Verification Goal": "Ensure that when the two pmpaddr MSBs are set, then no NAPOT accesses matches.\nEnsure that there are no attempted accesses to MSBs that the core should not be able to use.\n\nCover: all bits have been matched against (\"toggle cross\").", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "TODO missing assert\n\nTODO missing cover" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED).\n\nCOV: (SKIPPED)", + "Comment": "Assert and cover skipped in favor of model equivalence checking." }, { "Requirement Location": "", "Feature": "Csrs", "Sub Feature": "AddrImplemented", "Feature Description": "\"Not all physical address bits may be implemented, and so the pmpaddr registers are WARL.\"", - "Verification Goal": "Cover (toggle) that all bits can be both written and set. (UnusedZero below covers the WARL(0x0) case.)", + "Verification Goal": "Cover: (toggle) that all bits can be both written and set.\n\n(\"UnusedZero\" below covers the WARL(0x0) case.)", "Pass/Fail Criteria": "Other", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "COV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "COV: (SKIPPED)", + "Comment": "Skipped in favor of integration-level testing w/ release-specific configs." }, { "Requirement Location": "", "Feature": "AddressMatching", "Sub Feature": "MatchDisabled", "Feature Description": "\"When A=0, this PMP entry is disabled and matches no addresses\"\nWhen a cfg is set to off but its address(es) (interpreted as napot/tor) is the only rule that matches an attempted access, then it still does not count as a match.", - "Verification Goal": "Have a region's address(es) set up as tor and napot (separate runs), have all other regions not include the target address, have the target region's rule be OFF, make an access within that range, ensure that the outcome is the same as for when an access is outside of all address ranges.\n\nNote: For this and several other items, functional coverage is necessary because the checking doesn't necessarily have the above scenario in its antecedent.\n\nCoverage: Capture the above scenario, minus the checking.", + "Verification Goal": "Have a region's address(es) set up as tor and napot (separate runs),\nhave all other regions not include the target address,\nhave the target region's rule be OFF,\nmake an access within that range,\nensure that the outcome is the same as for when an access is outside of all address ranges.\n\nNote: For this and several other items, functional coverage is necessary because the checking doesn't necessarily have the above scenario in its antecedent.\n\nCoverage: Capture the above scenario, minus the checking.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", - "Comment": "TODO missing cover" + "High Priority?": "No", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA:\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (SKIPPED)", + "Comment": "Cover is skipped in favor of integration-level testing w/ release-specific configs, because we have equivalence checking of RTL vs model." }, { "Requirement Location": "", "Feature": "AddressMatching", "Sub Feature": "NapotMatching", "Feature Description": "\"NAPOT ranges make use of the low-order bits of the associated address register to encode the size of the range [\"yyyy...yy01\" etc]\"\n\nNote: The napot address matching modes match on addresses that are equal to the requested access when masked to the granularity size.", - "Verification Goal": "Configure napot rules of different sizes, try accesses within and outside the regions, ensure that the outcomes corresponds to the designated sizes.\n\nNote: Includes NAPOT and NA4.\n\nNote: Try also max and min.", + "Verification Goal": "Configure napot rules of different sizes.\nTry accesses within and outside the regions.\nEnsure that the outcomes corresponds to the designated sizes.\n\nNote: Includes NAPOT and NA4.\n\nCover: Matching inside / outside.\n\nCover: Min / Max of the \"yyy...\" patterns.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_na4is4byte.a_na4_is_4byte\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_cg_common.cover_item_covergroup_cg_internals_common_inst_cg_int_coverpoint_cp_napot_encoding_bin_auto[*]\ndut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_cg_common.cover_item_covergroup_cg_internals_common_inst_cg_int_coverpoint_cp_napot_encoding_disallowed_bin_auto[*]\n\nCOV: ???", - "Comment": "TODO missing coverage" + "High Priority?": "No", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_na4is4byte.a_na4_is_4byte\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_cg_common.cover_item_covergroup_cg_internals_common_inst_cg_int_coverpoint_cp_napot_encoding_bin_auto[*]\n\nCOV: dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_cg_common.cover_item_covergroup_cg_internals_common_inst_cg_int_coverpoint_cp_napot_encoding_disallowed_bin_auto[*]\n\nCOV: (SKIPPED).", + "Comment": "Cover skipped (min/max) in favor of model equivalence checking and trusting formal's capability of exercising the asserts." }, { "Requirement Location": "", "Feature": "AddressMatching", "Sub Feature": "TorMatching", "Feature Description": "\"If TOR is selected, the associated address register forms the top of the address range, and the preceding PMP address register forms the bottom of the address range. If PMP entry i\u2019s A field is set to TOR, the entry matches any address y such that pmpaddri\u22121 \u2264 y < pmpaddri (irrespective of the value of pmpcfgi\u22121)\"", - "Verification Goal": "Configure tor regions of different sizes, try accesses within and outside the regions, ensure that the outcomes corresponds to the designated ranges.", + "Verification Goal": "Configure tor regions of different sizes.\nTry accesses within and outside the regions.\nEnsure that the outcomes correspond to the designated ranges.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_cg_common.cover_item_covergroup_cg_internals_common_inst_cg_int_coverpoint_cp_ismatch_tor_bin_auto[*]\n\nCOV: ???", - "Comment": "TODO missing coverage" + "High Priority?": "No", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_cg_common.cover_item_covergroup_cg_internals_common_inst_cg_int_coverpoint_cp_ismatch_tor_bin_auto[*]", + "Comment": "" }, { "Requirement Location": "", @@ -229,9 +229,9 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???\n\nDTC: cv32e40s/tests/programs/custom/pmp/", - "Comment": "TODO missing cover" + "High Priority?": "No", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (SKIPPED)\n\nDTC: cv32e40s/tests/programs/custom/pmp/", + "Comment": "Cover skipped in favor of directed test and equivalence checking vs model." }, { "Requirement Location": "", @@ -242,9 +242,9 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???\n\nDTC: cv32e40s/tests/programs/custom/pmp/", - "Comment": "TODO missing cover" + "High Priority?": "No", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (SKIPPED)\n\nDTC: cv32e40s/tests/programs/custom/pmp/", + "Comment": "Cover skipped in favor of directed test and equivalence checking vs model." }, { "Requirement Location": "", @@ -255,9 +255,9 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED)", + "Comment": "Assert skipped in favor of the asserts checking the grain in general and model equivalence checking." }, { "Requirement Location": "", @@ -281,7 +281,7 @@ "Pass/Fail Criteria": "Other", "Test Type": "Other", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "High Priority", "Link to Coverage": "N/A", "Comment": "" }, @@ -308,8 +308,8 @@ "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_all_zeros_g1.gen_all_zeros_i[*].a_all_zeros\n\nCOV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_all_zeros_g1.gen_all_zeros_i[*].a_all_zeros\n\nCOV: uvmt_cv32e40s_pmp_assert.sv, \"cp_ismatch_tor\".\n\nCOV: uvmt_cv32e40s_pmp_assert.sv, \"cov_rlb_locked_rules_can_remove\".", + "Comment": "(The covers are written for a different purpose but should sufficiently hit this.)" }, { "Requirement Location": "", @@ -320,22 +320,22 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED)", + "Comment": "Assert skipped in favor of model equivalence checking." }, { "Requirement Location": "", "Feature": "AddressMatching", "Sub Feature": "StorageUnaffected", "Feature Description": "\"Although changing pmpcfgi.A[1] affects the value read from pmpaddri, it does not affect the underlying value stored in that register\"\n\"in particular, pmpaddri[G-1] retains its original value when pmpcfgi.A is changed from NAPOT to TOR/OFF then back to NAPOT.\"", - "Verification Goal": "Change in and out of (OFF || TOR) and !(OFF || TOR), ensure that different values can be read without having written anything new to the register.", + "Verification Goal": "Change in and out of (OFF || TOR) and !(OFF || TOR), ensure that different values can be read without having written anything new to the register.\n\nCover: All transitions, na4/napot -> off/tor.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_storage_unaffected[*].a_storage_unaffected\n\nCOV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_storage_unaffected[*].a_storage_unaffected\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped because assert is deemed sufficient." }, { "Requirement Location": "", @@ -359,7 +359,7 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -381,37 +381,37 @@ "Feature": "LockingAndPrivmode", "Sub Feature": "IgnoreWrites", "Feature Description": "\"If PMP entry i is locked, writes to pmpicfg and pmpaddri are ignored.\"", - "Verification Goal": "Lock entry i (for all i, if feasible), ensure that their value can't change, both when written to and otherwise. (Unless if RLB interferes.)", + "Verification Goal": "Lock entry i (for all i, if feasible), ensure that their value can't change. (Unless if RLB interferes.)\n\nCover: both when written to and otherwise.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_rlb_locked[*].a_norlb_locked_rules_cannot_modify uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_rlb_locked[*].a_norlb_locked_rules_cannot_modify\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_writes_notrap[*].a_ignore_writes_notrap\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_writes_nochange[*].a_ignore_writes_nochange\n\nCOV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_rlb_locked[*].a_norlb_locked_rules_cannot_modify uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_rlb_locked[*].a_norlb_locked_rules_cannot_modify\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_writes_notrap[*].a_ignore_writes_notrap\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_writes_nochange[*].a_ignore_writes_nochange\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped because the asserts are deemed sufficient." }, { "Requirement Location": "", "Feature": "LockingAndPrivmode", "Sub Feature": "IgnoreTor", "Feature Description": "\"Additionally, if PMP entry i is locked and pmpicfg.A is set to TOR, writes to pmpaddri-1 are ignored.\"", - "Verification Goal": "Lock entry i (\u2026), have A set and the mode be TOR, ensure that pmpaddri-1 can't change, both for explicit writes and otherwise. (Unless RLB.)", + "Verification Goal": "Lock entry i (\u2026), have A set and the mode be TOR, ensure that pmpaddri-1 can't change. (Unless RLB.)\n\nCover: both for explicit writes and otherwise", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_tor[*].a_ignore_tor_stable\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_tor[*].a_ignore_tor_wdata\n\nCOV: ???", - "Comment": "TODO missing cover" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_tor[*].a_ignore_tor_stable\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_ignore_tor[*].a_ignore_tor_wdata\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped because the asserts are deemed sufficient." }, { "Requirement Location": "", "Feature": "LockingAndPrivmode", "Sub Feature": "NotIgnore", "Feature Description": "When neither cfg i is locked, nor is cfg i+1 a locked TOR region, then writes to cfg and addr i are not ignored.", - "Verification Goal": "Have cfg i unlocked, write to cfg and addr csr i, check that it changes.", + "Verification Goal": "Have cfg i unlocked,\nwrite to cfg and addr csr i,\ncheck that it changes.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", + "High Priority?": "High Priority", "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_addr_writes[*].a_addr_nonlocked\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_addr_tor[*].a_addr_nonlocked_tor", "Comment": "" }, @@ -425,21 +425,21 @@ "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: (Same checking as for \"IgnoreWrites\" and \"IgnoreTor\" above.)\n\nCOV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "A: (Same checking as for \"IgnoreWrites\" and \"IgnoreTor\" above.)\n\nCOV: (SKIPPED).", + "Comment": "Cover skipped, trusting formal to exercise the assert." }, { "Requirement Location": "", "Feature": "LockingAndPrivmode", "Sub Feature": "RwxPrivmode", "Feature Description": "\"In addition to locking the PMP entry, the L bit indicates whether the R/W/X permissions are enforced on M-mode accesses. When the L bit is set, these permissions are enforced for all privilege modes.\"", - "Verification Goal": "Be in M-mode and U-mode (separate runs), access a region where L is set and where RWX {grant, deny R, deny W, deny X}, ensure that the access is correspondingly granted/denied.", + "Verification Goal": "Be in M-mode and U-mode (separate runs),\naccess a region where L is set and where RWX {grant, deny R, deny W, deny X},\nensure that the access is correspondingly granted/denied.\n\nCover: grant, deny R, deny W, deny X.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", - "Comment": "TODO missing cover" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped because the asserts are deemed sufficient." }, { "Requirement Location": "", @@ -450,35 +450,35 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED)", + "Comment": "Assert skipped in favor of Smepmp-based assertions." }, { "Requirement Location": "", "Feature": "LockingAndPrivmode", "Sub Feature": "RwxUmode", "Feature Description": "\"When the L bit is clear [\u2026] the R/W/X permissions apply only to S and U modes.\"", - "Verification Goal": "Be in U-mode, access a region where L is clear, ensure that access is granted/denied based on RWX.", + "Verification Goal": "Be in U-mode, access a region where L is clear, ensure that access is granted/denied based on RWX.\n\nCover: granted / denied.\n\nNote: The M-mode part of this is handled by \"MmodeSucceed\" above.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_uorl_onlyif_rwx\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_uorl_onlyif_rwx\n\nCOV: ???", - "Comment": "TODO missing cover" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_uorl_onlyif_rwx\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_uorl_onlyif_rwx\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped because the asserts are deemed sufficient." }, { "Requirement Location": "", "Feature": "PriorityAndMatching", "Sub Feature": "LowestDetermines", "Feature Description": "\"PMP entries are statically prioritized. The lowest-numbered PMP entry that matches any byte of an access determines whether that access succeeds or fails.\"\n\nNote: \"any\" byte.", - "Verification Goal": "Access a region that is covered by multiple rules, ensure that the lowest indexed match determines the outcome.\n\nNote: Requires that the rules would disagree on the outcome.", + "Verification Goal": "Access a region that is covered by multiple rules, ensure that the lowest indexed match determines the outcome.\n\nNote: Requires that the rules would disagree on the outcome. (One rule allows, other disallows.)\n\nCover: \"winning\" rule allows / disallows.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", - "Comment": "TODO missing cover" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (SKIPPED).", + "Comment": "Cover skipped, trusting formal to exercise the assert." }, { "Requirement Location": "", @@ -489,7 +489,7 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -498,13 +498,13 @@ "Feature": "PriorityAndMatching", "Sub Feature": "LrwxDetermines", "Feature Description": "\"If a PMP entry matches all bytes of an access, then the L, R, W,and X bits determine whether the access succeeds or fails. [...] if the L bit is set or the privilege mode of the access is S or U, then the access succeeds only if the R, W,or X bit corresponding to the access type is set.\"", - "Verification Goal": "Access a pmp region where L and the privmode etc is such that nothing else would deny the access, ensure that each of (or a combination of) RWX can either grant or deny the access.", + "Verification Goal": "Access a pmp region where L and the privmode etc is such that nothing else would deny the access, ensure that each of (or a combination of) RWX can either grant or deny the access.\n\nCover: U, M, L, grant, deny R, deny W, deny X, etc.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_lrwx_aftermatch\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_lrwx_aftermatch\n\nCOV: ???", - "Comment": "TODO missing cover" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_lrwx_aftermatch\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_lrwx_aftermatch\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped because the asserts are deemed sufficient. It is partially covered already by the \"general\" covergroup and its crosses." }, { "Requirement Location": "", @@ -515,7 +515,7 @@ "Pass/Fail Criteria": "Other", "Test Type": "Other", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -524,13 +524,13 @@ "Feature": "PriorityAndMatching", "Sub Feature": "MmodeNomatch", "Feature Description": "\"If no PMP entry matches an M-mode access, the access succeeds.\"", - "Verification Goal": "Be in M-mode, access a region where no rule matches, ensure that the access is granted (where MMWP is off).\n\n(Note, see \"Smepmp\" above.)", + "Verification Goal": "Be in M-mode,\naccess a region where no rule matches,\nensure that the access is granted (where MMWP is off).\n\nCover: the checker is generic, so cover this specific scenario.\n\n(Note, see \"Smepmp\" above.)", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nCOV: ???", - "Comment": "TODO missing cover" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nCOV: uvmt_cv32e40s_pmp_assert.sv, \"cp_x_mmode_nomatch_nommwp_x\".\n\nCOV: uvmt_cv32e40s_pmp_assert.sv, \"cp_r_mmode_nomatch_nommwp_r\".\n\nCOV: uvmt_cv32e40s_pmp_assert.sv, \"cp_w_mmode_nomatch_nommwp_w\".", + "Comment": "" }, { "Requirement Location": "", @@ -540,23 +540,23 @@ "Verification Goal": "Be in U-mode, do an access that doesn't match any region, ensure that the access fails.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", - "Coverage Method": "Functional Coverage", + "Coverage Method": "Assertion Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_nomatch_umode_fails\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_nomatch_umode_fails\n\nCOV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_nomatch_umode_fails\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_nomatch_umode_fails", + "Comment": "" }, { "Requirement Location": "", "Feature": "PriorityAndMatching", "Sub Feature": "UmodeOff", "Feature Description": "\"If at least one PMP entry is implemented, but all PMP entries\u2019 A fields are set to OFF, then all S-mode and U-mode memory accesses will fail.\"", - "Verification Goal": "Be in U-mode, have all entries OFF, make an access, ensure that the access fails (for all variations of accesses).", + "Verification Goal": "Be in U-mode,\nhave all entries OFF,\nmake an access,\nensure that the access fails.\n\nCover: this specific scenario.\n\nCover: for all variations of accesses", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", - "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", - "Comment": "TODO missing cover" + "Coverage Method": "Assertion Coverage", + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_umode_off\".\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (SKIPPED)", + "Comment": "Second cover skipped because it should be the responsibility of the \"general\" covergroup and its crosses." }, { "Requirement Location": "", @@ -566,62 +566,62 @@ "Verification Goal": "Cause failed accesses on instructions/loads/stores, ensure that an exception occurs and that it is the right one.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", - "Coverage Method": "Functional Coverage", + "Coverage Method": "Assertion Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_*\n\nA: ::uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_*\n\nCOV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_*\n\nA: ::uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_*", + "Comment": "" }, { "Requirement Location": "", "Feature": "PriorityAndMatching", "Sub Feature": "MultiAccess", "Feature Description": "\"Note that a single instruction may generate multiple accesses, which may not be mutually atomic. An access-fault exception is generated if at least one access generated by an instruction fails, though other accesses generated by that instruction may succeed with visible side effects.\"\n\n\"On some implementations, misaligned loads, stores, and instruction fetches may also be decomposed into multiple accesses, some of which may succeed before an access-fault exception occurs. In particular, a portion of a misaligned store that passes the PMP check may become visible, even if another portion fails the PMP check.\"", - "Verification Goal": "Induce misaligned word instruction-fetch, load, and store, where the lower and upper (separate runs) parts are either accessible or blocked by pmp, ensure that exceptions occur while parts of the access might reach the bus.\n\nAlso check Zc's push/pop and table jump.\n\nNote: It is up to other vplans to check what happens upon the exception. It is up to this PMP vplan to check that the PMP will cause the exceptions.", + "Verification Goal": "Induce misaligned word instruction-fetch, load, and store, where the lower and upper (separate runs) parts are either accessible or blocked by pmp, ensure that exceptions occur while parts of the access might reach the bus.\n\nCover: upper/lower blocked/allowed.\n\nCover: parts reaching the bus.\n\nCover: push/pop and table jump.\n\nNote: It is up to other vplans to check what happens upon the exception. It is up to this PMP vplan to check that the PMP will cause the exceptions.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_splittrap\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_splittrap\n\nA: ???\n\nCOV: ???", - "Comment": "TODO missing assert (on split that errs on first)\n\nTODO missing cover" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec*\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore*\n\nA: (SKIPPED)\n\nCOV: (SKIPPED)", + "Comment": "Assert skipped (explicitly, split that errs on first) because it is theoretically covered by the generic assert.\n\nSpecific covers skipped, in favor of trusting formal's ability to exercise the asserts." }, { "Requirement Location": "smepmp", "Feature": "MsecCfg", "Sub Feature": "MmodeOnly", - "Feature Description": "\"Machine Security Configuration (mseccfg) is [...] only accessible to Machine mode.\"\n\nNote: Includes \"mseccfgh\".", - "Verification Goal": "Access (read/write) mseccfg (and mseccfgh) from M-mode, access mseccfg from U-mode, ensure that the first always works (WARL) and the second never works (exception).\n\nNote: Cover with MPRV too.", + "Feature Description": "\"Machine SECurity ConFiGuration (mseccfg) is [...] only accessible to Machine mode.\"\n\nNote: Includes \"mseccfgh\".", + "Verification Goal": "Access (read/write) mseccfg (and mseccfgh) from M-mode, access mseccfg from U-mode, ensure that the first always works (WARL) and the second never works (exception).\n\nNote: Cover with MPRV too.\n\nCover: read/write, mmode/umode, mprv/no, mseccfg/mseccfgh.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", - "Coverage Method": "Assertion Coverage", + "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "Link to Coverage": "A: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_csrs_mmode_only\".\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped, trusting formal to exercise the assert." }, { "Requirement Location": "", "Feature": "MsecCfg", "Sub Feature": "FieldsWarl", "Feature Description": "\"All mseccfg fields defined on this proposal are WARL\"", - "Verification Goal": "Try writing any values to the fields (the defined ones, but also other bits) and read values out of the fields, ensure that neither reads nor writes causes exceptions, and ensure that all read values are legal or otherwise as expected.\n\nNote: This relates to the \"stickiness\" of those fields. Regardless of their values and current stickiness, the fields are WARL.\n\nNote: It might be difficult, when trying to write a checker for traps, to filter out all other causes for traps that can occur simultaneously. (Either reduce the scope of checking, or write re-usable helper signals for \"trap causality\" info.)\n\nNote: \"WPRI\" on some bits.", + "Verification Goal": "Try writing any values to the fields (the defined ones, but also other bits) and read values out of the fields, ensure that neither reads nor writes causes exceptions, and ensure that all read values are legal or otherwise as expected.\n\nNote: This relates to the \"stickiness\" of those fields. Regardless of their values and current stickiness, the fields are WARL.\n\nNote: \"WPRI\" on some bits.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "TODO missing assert\n\nTODO missing cover" + "High Priority?": "No", + "Link to Coverage": "A: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_csrs_mmode_only\".\n\nA: (SKIPPED)\n\nCOV: (SKIPPED)", + "Comment": "Second assert skipped because the features themselves are covered by other asserts and integration testing.\n\nCover skipped for the same reasons as the assert and also because the covergroups in uvmt_cv32e40s_pmp_assert.sv covers parts of it." }, { "Requirement Location": "", "Feature": "MsecCfg", "Sub Feature": "ReservedZero", - "Feature Description": "\"the remaining bits are reserved for future standard use and should always read zero.\"\n(This spec can't dictate that about other specs, but the user manual agrees on the hardwiring.)", + "Feature Description": "\"the remaining bits are reserved for future standard use and should always read zero.\"\n\n(Note: This spec can't dictate that about other specs, but the user manual agrees on the hardwiring.)", "Verification Goal": "Read mseccfg, ensure the non-smepmp-field bits are always zero.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "Link to Coverage": "A: uvmt_cv32e40s_pmp_assert.sv, \"a_reserved_zero_mseccfg_fields\".", + "Comment": "" }, { "Requirement Location": "", @@ -645,9 +645,9 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_addr\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_exec\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_lock\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_mode\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_read\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].c_rlb_locked_rules_can_modify_write\n\nCOV: ???", - "Comment": "TODO missing assert" + "High Priority?": "High Priority", + "Link to Coverage": "A: N/A\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_addr\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_exec\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_lock\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_mode\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_read\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.*.gen_rlb_locked_cov[*].cov_rlb_locked_rules_can_modify_write\n\nCOV: uvmt_cv32e40s_pmp_assert.sv, \"cov_rlb_locked_rules_can_modify_tor\".", + "Comment": "The assert is N/A because the covers are the checkers." }, { "Requirement Location": "", @@ -667,13 +667,13 @@ "Feature": "LockingBypass", "Sub Feature": "UntilReset", "Feature Description": "The sticky zero and update-ignores last until reset, and do not hold after reset.", - "Verification Goal": "Ensure that RLB is modifiable after reset. (Unless if reset values are set to activate the RemainZero condition.)", + "Verification Goal": "Ensure that RLB is modifiable after reset. (Unless if reset values are set to activate the RemainZero condition.)\n\nNote: Both enable / disable.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", - "Coverage Method": "Functional Coverage", + "Coverage Method": "Assertion Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_until_reset_notbefore\n\nCOV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_until_reset_notbefore", + "Comment": "" }, { "Requirement Location": "", @@ -684,7 +684,7 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -706,39 +706,39 @@ "Feature": "WhiteList", "Sub Feature": "Denied", "Feature Description": "\"When set it changes the default PMP policy for M-mode when accessing memory regions that don\u2019t have a matching PMP rule, to denied instead of ignored.\"", - "Verification Goal": "Have MMWP set, be in (effective mode) M-mode, access regions that don't match any rule (including OFF, \"reversed\" TOR, >32bit NAPOT, etc), ensure that the access is denied.", + "Verification Goal": "Have MMWP set,\nbe in (effective mode) M-mode,\naccess regions that don't match any rule (including OFF, \"reversed\" TOR, >32bit NAPOT, etc),\nensure that the access is denied.\n\nCover: MPRV/no, off/reversed/napot.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_nomatch_mmode_mmwp_fails\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_nomatch_mmode_mmwp_fails\n\nCOV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_nomatch_mmode_mmwp_fails\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_nomatch_mmode_mmwp_fails\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped because assert is deemed sufficient." }, { "Requirement Location": "", "Feature": "LockdownGeneral", "Sub Feature": "StickyUntilReset", "Feature Description": "\"[mseccfg.MML] is a sticky bit, meaning that once set it cannot be unset until a PMP reset.\"", - "Verification Goal": "Cover: Trying to clear the bit.\n\nCheck: Have MML set, ensure that it remains high forever (til reset).", + "Verification Goal": "Check: Have MML set, ensure that it remains high forever (til reset).\n\nCover: Trying to clear the bit.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_mml_never_fall_until_reset\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_mml_never_fall_until_reset\n\nCOV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_pmp_assert.a_mml_never_fall_until_reset\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_mml_never_fall_until_reset\n\nCOV: (Skipped)", + "Comment": "Cover skipped because assert is deemed sufficient." }, { "Requirement Location": "", "Feature": "LockdownGeneral", "Sub Feature": "ExecIgnored", "Feature Description": "\"[When mseccfg.MML is set.] Adding an M-mode-only or a locked Shared-Region rule with executable privileges is not possible and such pmpcfg writes are ignored, leaving pmpcfg unchanged.\"\n\nNote: \"pmpcfg\" refers to a field, so the write to the CSR itself should still update other fields.", - "Verification Goal": "Have MML set, try adding an \"M-mode-only\" rule and a \"locked Shared-Region\" rule with X privileges, ensure that the relevant pmpcfg field is not updated but is left unchanged, ensure also that other fields can still get updated.", + "Verification Goal": "Have MML set,\ntry adding an \"M-mode-only\" rule and a \"locked Shared-Region\" rule with X privileges,\nensure that the relevant pmpcfg field is not updated but is left unchanged,\nensure also that other fields can still get updated.\n\nCover: M-mode-only / Shared-Region.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgwdata_legal[*].a_cfgwdata_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_rlb_locked_cov[0].a_mmode_only_or_shared_executable_ignore\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_rlb_locked_cov[0].a_mmode_only_or_shared_executable_ignore\n\nCOV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgwdata_legal[*].a_cfgwdata_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_rlb_locked_cov[0].a_mmode_only_or_shared_executable_ignore\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_rlb_locked_cov[0].a_mmode_only_or_shared_executable_ignore\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped because assert is deemed sufficient." }, { "Requirement Location": "", @@ -758,13 +758,13 @@ "Feature": "LockdownGeneral", "Sub Feature": "MmodeExec", "Feature Description": "\"Executing code with Machine mode privileges is only possible from memory regions with a matching M-mode-only rule or a locked Shared-Region rule with executable privileges. Executing code from a region without a matching rule or with a matching S/U-mode-only rule is denied.\"", - "Verification Goal": "Execute from \"M-mode-only\" and \"locked Shared-Region\" regions, attempt execution without matching and from \"U-mode-only\" regions, ensure corresponding grant or deny.", + "Verification Goal": "Execute from \"M-mode-only\" and \"locked Shared-Region\" regions,\nattempt execution without matching and from \"U-mode-only\" regions,\nensure corresponding grant or deny.\n\nCover: The different scenarios.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", - "Comment": "TODO missing cover" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped because assert is deemed sufficient." }, { "Requirement Location": "", @@ -784,39 +784,39 @@ "Feature": "LockdownA", "Sub Feature": "MmodeEnforce", "Feature Description": "\"[When mseccfg.MML is set.] An M-mode-only rule is enforced on Machine mode\"", - "Verification Goal": "Be in M-mode, have MML set, access an \"M-mode-only\" region, ensure that the grant/deny is always in accordance to the rule. (E.g. it is not denied execute despite the execute bit being set.)\n\nNote: Exclude cases of interference from e.g. PMA.", + "Verification Goal": "Be in M-mode,\nhave MML set,\naccess an \"M-mode-only\" region,\nensure that the grant/deny is always in accordance to the rule.\n(E.g. it is not denied execute despite the execute bit being set.)\n\nCover: grant / deny for this specific scenario.\n\nNote: Exclude cases of interference from e.g. PMA.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", - "Comment": "(Same as for \"MmodeDeny\")" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (SKIPPED)", + "Comment": "(Same as for \"MmodeDeny\")\n\nCover skipped because assert is deemed sufficient." }, { "Requirement Location": "", "Feature": "LockdownA", "Sub Feature": "UmodeDeny", "Feature Description": "\"[When mseccfg.MML is set.] An M-mode-only rule is [...] denied in Supervisor or User mode.\"", - "Verification Goal": "Be in U-mode, have MML set, access an \"M-mode-only\" region, ensure that the access is always denied.", + "Verification Goal": "Be in U-mode,\nhave MML set,\naccess an \"M-mode-only\" region,\nensure that the access is always denied.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "High Priority", + "Link to Coverage": "A: (SKIPPED)", + "Comment": "Explicit assert skipped in favor of model equivalence checking." }, { "Requirement Location": "", "Feature": "LockdownA", "Sub Feature": "RemainLocked", - "Feature Description": "\"It also remains locked so that any further modifications to its associated configuration or address registers are ignored until a PMP reset\"\n\nCertain rules under MML are sticky. They cannot be modified again.", - "Verification Goal": "Configure rules for {\"M-mode-only\", \"U-mode-only, \"Shared-Region rule where pmpcfg.L is set\"(both kinds)}, have MML=1 (and RLB=0), ensure that the configs never change again (until reset).", + "Feature Description": "\"[An M-mode-only rule] also remains locked so that any further modifications to its associated configuration or address registers are ignored until a PMP reset\"\n\nCertain rules under MML are sticky. They cannot be modified again.", + "Verification Goal": "1) Configure for \"M-mode-only,\n2) have MML=1 (and RLB=0),\n3) ensure that the configs never change again (until reset).\n\nCover: with mml=1. (Since the assert re-uses a different vplan item's assert.)", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "TODO missing assert" + "Link to Coverage": "A: (See IgnoreWrites)\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped because assert is deemed sufficient." }, { "Requirement Location": "", @@ -828,46 +828,46 @@ "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "TODO missing assert" + "Link to Coverage": "A: (see \"ModifiableEntries\")\n\nCOV: (See \"ModifiableEntries\")", + "Comment": "" }, { "Requirement Location": "", "Feature": "LockdownA", "Sub Feature": "UmodeEnforce", "Feature Description": "\"[When mseccfg.MML is set.] An S/U-mode-only rule is enforced on Supervisor and User modes \"", - "Verification Goal": "Be in U-mode, have MML=1, access a \"U-mode-only\" region, ensure that the grant/deny is in accordance with the rule (apart from PMA etc).", + "Verification Goal": "1) Be in U-mode,\n2) have MML=1,\n3) access a \"U-mode-only\" region,\n4) ensure that the grant/deny is in accordance with the rule (apart from PMA etc).\n\nCover: Grant / deny.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_cp_data_side.cg_data\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_cp_instr_side.cg_instr\n\nCOV: ???", - "Comment": "(Same as for \"MmodeDeny\")" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_cp_data_side.cg_data\n\nCOV: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_cp_instr_side.cg_instr\n\nCOV: (SKIPPED)", + "Comment": "(Same as for \"MmodeDeny\")\n\nSkipped cover for explicit deny, in favor of model equivalence checking." }, { "Requirement Location": "", "Feature": "LockdownA", "Sub Feature": "MmodeDeny", "Feature Description": "\"An S/U-mode-only rule is [...] denied on Machine mode.\"", - "Verification Goal": "Be in M-mode, have MML=1, access a \"U-mode-only\" region, ensure that the access is always denied.", + "Verification Goal": "1) Be in M-mode,\n2) have MML=1,\n3) access a \"U-mode-only\" region,\n4) ensure that the access is always denied.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", - "Comment": "TODO missing coverage. (Just do a cg with crosses of all of these variables.)" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped in favor of model equivalence checking." }, { "Requirement Location": "", "Feature": "LockdownA", "Sub Feature": "SharedEnforced", "Feature Description": "\"A Shared-Region rule is enforced on all modes\"", - "Verification Goal": "Be in M-mode and U-mode (separate runs), access a \"Shared-Region\", ensure that the grant/deny is in accordance with the rule.", + "Verification Goal": "1) Be in M-mode and U-mode (separate runs),\n2) access a \"Shared-Region\",\n3) ensure that the grant/deny is in accordance with the rule.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (See \"UmodeEnforce\").", "Comment": "(Same as for \"MmodeDeny\")" }, { @@ -875,12 +875,12 @@ "Feature": "LockdownA", "Sub Feature": "SharedNoexec", "Feature Description": "\"A Shared-Region rule where pmpcfg.L is not set can be used for sharing data between M-mode and S/U-mode, so is not executable.\"", - "Verification Goal": "Be in M-mode and U-mode, try to execute from \"A Shared-Region rule where pmpcfg.L is not set\", ensure that it does not work (exception).", + "Verification Goal": "1) Be in M-mode and U-mode,\n2) try to execute from \"A Shared-Region rule where pmpcfg.L is not set\",\n3) ensure that it does not work (exception).", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (See \"MmodeDeny\").", "Comment": "(Same as for \"MmodeDeny\")" }, { @@ -888,12 +888,12 @@ "Feature": "LockdownA", "Sub Feature": "MmodeReadwrite", "Feature Description": "\"[Shared-Region rule where pmpcfg.L is not set.] M-mode has read/write access to that region\"", - "Verification Goal": "Be in M-mode, perform reads and writes to such a region, ensure that the intended effects happen and that the accesses do not cause exceptions.", + "Verification Goal": "1) Be in M-mode,\n2) perform reads and writes to such a region,\n3) ensure that the intended effects happen and that the accesses do not cause exceptions.\n\nCover: read / write.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (See \"MmodeDeny\").", "Comment": "(Same as for \"MmodeDeny\")" }, { @@ -905,8 +905,8 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (See \"MmodeDeny\").", "Comment": "(Same as for \"MmodeDeny\")" }, { @@ -918,8 +918,8 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (See \"MmodeDeny\").", "Comment": "(Same as for \"MmodeDeny\")" }, { @@ -931,8 +931,8 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (See \"MmodeDeny\").", "Comment": "(Same as for \"MmodeDeny\")" }, { @@ -944,8 +944,8 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: ???", + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (See \"MmodeDeny\").", "Comment": "(Same as for \"MmodeDeny\")" }, { @@ -957,7 +957,7 @@ "Pass/Fail Criteria": "Other", "Test Type": "Other", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "High Priority", "Link to Coverage": "N/A", "Comment": "" }, @@ -970,9 +970,9 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\nuvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_cp_instr_side.cover_item_covergroup_cg_internals_instr_side_inst_cg_instr_coverpoint_cp_r_mmode_mml_lrwx\n\nCOV: dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_cp_data_side.cover_item_covergroup_cg_internals_data_side_inst_cg_instr_coverpoint_cp_r_mmode_mml_lrwx\n\nCOV: dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_cp_data_side.cover_item_covergroup_cg_internals_data_side_inst_cg_instr_coverpoint_cp_r_umode_mml_lrwx\n\nCOV: ???", - "Comment": "TODO technically missing the \"the rest \u2026 excepts\" cover" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i.u_pmp_assert_if_stage.gen_cp_instr_side.cover_item_covergroup_cg_internals_instr_side_inst_cg_instr_coverpoint_cp_r_mmode_mml_lrwx\n\nCOV: dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_cp_data_side.cover_item_covergroup_cg_internals_data_side_inst_cg_instr_coverpoint_cp_r_mmode_mml_lrwx\n\nCOV: dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_cp_data_side.cover_item_covergroup_cg_internals_data_side_inst_cg_instr_coverpoint_cp_r_umode_mml_lrwx\n\nCOV: (SKIPPED)", + "Comment": "Non-exhaustive covers, in favor of model equivalence checking (technically missing the \"the rest \u2026 excepts\" cover)." }, { "Requirement Location": "", @@ -983,7 +983,7 @@ "Pass/Fail Criteria": "Other", "Test Type": "Other", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "High Priority", "Link to Coverage": "N/A", "Comment": "" }, @@ -1009,22 +1009,22 @@ "Pass/Fail Criteria": "Other", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "COV: ???", - "Comment": "TODO missing cover" + "High Priority?": "No", + "Link to Coverage": "COV: uvmt_cv32e40s_pmp_assert.sv, \"cg_internals_*\".\n\nCOV: (SKIPPED)", + "Comment": "Cover skipped for all explicit variations of \"denied\", in favor of model equivalence checking." }, { "Requirement Location": "manual", "Feature": "Parameters", "Sub Feature": "MinimumGranularity", "Feature Description": "\"The PMP_GRANULARITY parameter is used to configure the minimum granularity of PMP address matching. The minimum granularity is [2^(PMP_GRANULARITY+2)] bytes, so at least 4 bytes.\"", - "Verification Goal": "Have runs with max granularity, minimum granularity, and something in between. Make sure all checkers/covers are active for each relevant run configuration, so tor/napot/na4 is tested with different granularities. Cover cases where a match would otherwise occur but the granularity made the access not match.\n\nNote: Ensure TorMatching etc above heed this parameter.", + "Verification Goal": "Have runs with max granularity, minimum granularity, and something in between. Make sure all checkers/covers are active for each relevant run configuration, so tor/napot/na4 is tested with different granularities.\n\nCover: cases where a match would otherwise occur but the granularity made the access not match.\n\nNote: Ensure TorMatching etc above heed this parameter.", "Pass/Fail Criteria": "Other", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "COV: ???", - "Comment": "TODO missing cover" + "High Priority?": "No", + "Link to Coverage": "COV: (SKIPPED)", + "Comment": "Cover skipped in favor of release-specific configs and the rest of the tests/asserts." }, { "Requirement Location": "", @@ -1035,9 +1035,9 @@ "Pass/Fail Criteria": "Other", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "COV: ???", - "Comment": "TODO missing cover" + "High Priority?": "No", + "Link to Coverage": "COV: (SKIPPED)", + "Comment": "Cover skipped in favor of release-specific configs." }, { "Requirement Location": "", @@ -1048,9 +1048,9 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", "Coverage Method": "Functional Coverage", - "High Priority?": "High Priority", - "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "TODO missing assert\n\nTODO missing cover" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED)\n\nCOV: (SKIPPED)", + "Comment": "Assert and cover skipped in favor of release-specific configs and integration-level testing." }, { "Requirement Location": "", @@ -1061,7 +1061,7 @@ "Pass/Fail Criteria": "Other", "Test Type": "Other", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -1070,24 +1070,24 @@ "Feature": "CSRs", "Sub Feature": "AlwaysAccessible", "Feature Description": "\"All PMP CSRs are always implemented\". \"MRW\". The CSRs are M-mode accessible, and their existence does not depend on PMP_NUM_REGIONS.\n\nNote: \"All\" pmp registers, and all fields within them.", - "Verification Goal": "Be in M-mode, access (reads/writes) all the pmp csrs, ensure that it always works without excepting (because the csrs exist and the mode is appropriate).\n\nNote: Potential overlap with CSR vplan.", + "Verification Goal": "1) Be in M-mode,\n2) access (reads/writes) all the pmp csrs,\n3) ensure that it always works without excepting (because the csrs exist and the mode is appropriate).\n\nNote: Potential overlap with CSR vplan.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Directed Non-Self-Checking", "Coverage Method": "Assertion Coverage", - "High Priority?": "High Priority", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_always_accessible_mmode_csrs\".", + "Comment": "" }, { "Requirement Location": "", "Feature": "CSRs", "Sub Feature": "ReservedLegal", "Feature Description": "Reserved bits/fields have legal values, matching the platform-specified defaults.", - "Verification Goal": "(Overlaps with LegalRwx and RwReservedabove.) Read all fields of all pmp-related csrs, ensure there are no unsupported values anywhere (at all times).", + "Verification Goal": "(Overlaps with LegalRwx and RwReservedabove.)\nRead all fields of all pmp-related csrs, ensure there are no unsupported values anywhere (at all times).", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", + "High Priority?": "High Priority", "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.gen_cfgrdata_expected[*].a_cfgrdata_expected", "Comment": "" }, @@ -1101,21 +1101,21 @@ "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "Link to Coverage": "A: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_mseccfgh_zero\".", + "Comment": "" }, { "Requirement Location": "", "Feature": "CSRs", "Sub Feature": "UnusedZero", "Feature Description": "\"CSRs (or bitfields of CSRs) related to PMP entries with number PMP_NUM_REGIONS and above are hardwired to zero.\"\n\nNote: Including upper parts of pmpcfgn and also pmpaddr.", - "Verification Goal": "Read pmpcfg and pmpaddr csrs, ensure the values are zero as specified. Cover that the other values can be non-zero.", + "Verification Goal": "1) Read pmpcfg and pmpaddr csrs,\n2) ensure the values are zero as specified.\n\nCover: that the other values can be non-zero.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "High Priority", - "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "TODO missing assert\n\nTODO missing cover" + "High Priority?": "No", + "Link to Coverage": "A: uvmt_cv32e40s_pmp_assert.sv, \"a_unused_zero_pmp_csrs\".\n\nCOV: (SKIPPED).", + "Comment": "Cover skipped as not important." }, { "Requirement Location": "", @@ -1126,7 +1126,7 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "High Priority", "Link to Coverage": "N/A", "Comment": "" }, @@ -1138,10 +1138,10 @@ "Verification Goal": "The pmp grant/deny checking must be compared vs \"rvfi_csr__rdata\".\n(This will detect whether the actual pmp decision differs from what the rvfi csr data would incidate.)\n\nNote: Compare \"pc_rdata\" for execute, and \"mem_\" signals for read/write. (Might need additional decoding of \"rvfi_insn\".)", "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", - "Coverage Method": "Functional Coverage", + "Coverage Method": "Assertion Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_musttrap\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_load\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_store\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_splittrap\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_musttrap\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_cause\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_splittrap\n\nCOV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_musttrap\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_load\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_store\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_splittrap\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_musttrap\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_cause\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_splittrap", + "Comment": "" }, { "Requirement Location": "", @@ -1152,9 +1152,9 @@ "Pass/Fail Criteria": "Check against RM", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "COV: ???", - "Comment": "TODO missing cover" + "High Priority?": "No", + "Link to Coverage": "COV: (SKIPPED)", + "Comment": "Cover skipped because random testing of pmp proved to be low ROI." }, { "Requirement Location": "", @@ -1178,7 +1178,7 @@ "Pass/Fail Criteria": "Other", "Test Type": "Other", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -1191,7 +1191,7 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -1204,7 +1204,7 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -1213,13 +1213,13 @@ "Feature": "MicroArchitecture", "Sub Feature": "WriteBuffer", "Feature Description": "Changes to the pmp config should not impact the write buffer such that a transaction can get its grant/deny status altered.", - "Verification Goal": "Cover cases of the write buffer being full while the pmp cfg changes. Checking of accidental grants is handled by SuppressReq below. Checking of guaranteed writes is not part of this vplan.\n\nNote: The Write buffer is situated between the pmp and the bus.", + "Verification Goal": "Cover cases of the write buffer being full while the pmp cfg changes. Checking of accidental grants is handled by SuppressReq below.\nChecking of guaranteed writes is not part of this vplan.\n\nNote: The Write buffer is situated between the pmp and the bus.", "Pass/Fail Criteria": "Other", "Test Type": "Other", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "COV: ???", - "Comment": "TODO missing cover" + "Link to Coverage": "COV: (See \"WaitUpdate\").", + "Comment": "" }, { "Requirement Location": "", @@ -1243,7 +1243,7 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -1256,7 +1256,7 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", + "High Priority?": "High Priority", "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_cause", "Comment": "" }, @@ -1265,39 +1265,39 @@ "Feature": "Violations", "Sub Feature": "ExceptionLoad", "Feature Description": "\"mcause [...] Load access fault [...] Load attempt with address failing PMP check.\"\n\nNote: Holds for load-reserved too.", - "Verification Goal": "Attempt loads (and load-reserveds) of a region that pmp denies reading from, ensure that a \"load access fault\" exception occurs (read mcause and rvfi signals).", + "Verification Goal": "1) Attempt loads (and load-reserveds) of a region that pmp denies reading from,\n2) ensure that a \"load access fault\" exception occurs (read mcause and rvfi signals).\n\nCover: normal / load-reserved / pop.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_load\n\nCOV: ???", - "Comment": "TODO missing cover" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_load\n\nCOV: (SKIPPED).", + "Comment": "Cover skipped as \"rvfi_if.is_load_instr\" should handle all load types." }, { "Requirement Location": "", "Feature": "Violations", "Sub Feature": "ExceptionStore", "Feature Description": "\"mcause [...] Store/AMO access fault [...] Store attempt with address failing PMP check.\"\n\nNote: Holds for store-conditional and amo too.", - "Verification Goal": "Attempt stores (and store-conditionals and amo) to a region that pmp denies writing to, ensure that a \"store/amo access fault\" exception occurs (read mcause and rvfi signals).", + "Verification Goal": "1) Attempt stores (and store-conditionals and amo) to a region that pmp denies writing to,\n2) ensure that a \"store/amo access fault\" exception occurs (read mcause and rvfi signals).", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_store\n\nCOV: ???", - "Comment": "TODO missing cover" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_cause_store\n\nCOV: (SKIPPED).", + "Comment": "Cover skipped as \"rvfi_if.is_store_instr\" should handle all store types." }, { "Requirement Location": "", "Feature": "Violations", "Sub Feature": "TrapPrecisely", "Feature Description": "\"All exceptions are precise\".\nMeaning mepc will point to the offending instruction, and exactly previous instructions have their side effects fully visible.\n\nNote: Applies to loads, stores, and executes.", - "Verification Goal": "Observe that the pmp causes an exception, ensure that mepc points to the offending instruction.\n\nNote: Let the Exceptions vplan deal with visibility of side effects for earlier instructions. (Zc push/pop does not follow this, but that is mostly the responsibility of the Zc vplan.)\n\nNote: If satisfactory mepc checking already exist then it is acceptable to just add covers for the pmp scenarios.", + "Verification Goal": "Observe that the pmp causes an exception, ensure that mepc points to the offending instruction.\n\nNote: Let the Exceptions vplan deal with visibility of side effects for earlier instructions.\n(Zc push/pop does not follow this, but that is mostly the responsibility of the Zc vplan.)\n\nNote: If satisfactory mepc checking already exist then it is acceptable to just add covers for the pmp scenarios.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "TODO missing assert\n\nTODO missing cover" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED).\n\nCOV: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_noexec_cause\".\n\nCOV: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_noloadstore_cause_load\".\n\nCOV: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_noloadstore_cause_store\".", + "Comment": "Assertion skipped because 1) we don't have readily-available helper signals for non-clic pointers, and 2) this is not a high priority assert. (It could be easy to write and assert that mepc is pc_rdata, with some exceptions to that rule.)" }, { "Requirement Location": "", @@ -1308,8 +1308,8 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nCOV: ???", + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_xsecure_security_alerts_assert.sv, \"a_xsecure_security_alert_non_nmi_exceptions\".\n\nCOV: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_noexec_cause\".\n\nCOV: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_noloadstore_cause_load\".\n\nCOV: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_noloadstore_cause_store\".", "Comment": "Waiting for xsecure vplan" }, { @@ -1321,9 +1321,9 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED).", + "Comment": "Assert skipped in favor of deeming the xsecure verification and integration-level testing sufficient." }, { "Requirement Location": "", @@ -1334,48 +1334,48 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "Waiting for exceptions vplan" + "High Priority?": "No", + "Link to Coverage": "A: uvmt_cv32e40s_rvfi_assert.sv, \"a_exceptions_dont_update_gprs\".", + "Comment": "" }, { "Requirement Location": "", "Feature": "Violations", "Sub Feature": "SplitLoadException", "Feature Description": "For split loads, regardless of which of the access that fails, the instruction should still cause an exception.", - "Verification Goal": "Perform a misaligned load that translates to multiple accesses, let any of the accesses be denied by pmp, ensure an exception occurs.\n\nCoverage: See rvfi retire with exception cause from pmp, while the \"low addr\" model checking gave access granted.", + "Verification Goal": "1) Perform a misaligned load that translates to multiple accesses,\n2) let any of the accesses be denied by pmp,\n3) ensure an exception occurs.\n\nCoverage: See rvfi retire with exception cause from pmp, while the \"low addr\" model checking gave access granted.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", - "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "TODO missing assert\n\nTODO missing cover" + "Coverage Method": "Assertion Coverage", + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_noloadstore_splittrap\".", + "Comment": "Note: The assert only checks that the 2nd access is denied, not the general case of _any_." }, { "Requirement Location": "", "Feature": "Violations", "Sub Feature": "FirstFail", "Feature Description": "If a split load/store fails on its first transaction it should get an exception immediately, so it should not allow the second transaction reach the bus and mcause shall reflect the failing transactions.", - "Verification Goal": "Attempt such an instruction, ensure that the denied access does not reach the bus, ensure that following accesses also do not reach the bus.", + "Verification Goal": "1 Attempt such an instruction,\n2) ensure that the denied access does not reach the bus,\n3) ensure that following accesses also do not reach the bus.\n\nCover: load / store.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_rvfi_mem_allowed_data\".\n\nA: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_rvfi_mem_allowed_upperdata\".", + "Comment": "Note: Trusting RVFI to report OBI actuals truthfully." }, { "Requirement Location": "", "Feature": "Violations", "Sub Feature": "PushPop", "Feature Description": "If a push/pop fails on a transaction it should get an exception immediately, so the remaining transactions should not reach the bus and mcause shall reflect the failing transaction.", - "Verification Goal": "(Responsibility of the zc vplan. But link to coverage here too.)\n\nNote: Could write a pmp-specific cover, but coordinate with Zc vplan to ensure the checker is written too.", + "Verification Goal": "(Responsibility of the zc vplan. But link to coverage here too.)\n\nCover: could write a pmp-specific cover, but coordinate with Zc vplan to ensure the checker is written too.", "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "Waiting for zc vplan" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.u_zc_assert.a_multiop_exception_stop_dbus_push\n\nA: A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.u_zc_assert.a_multiop_exception_stop_dbus_pop\n\nCOV: (SKIPPED).", + "Comment": "Cover skipped in favor of trusting that formal will exercise the assert for pmp-specific cases." }, { "Requirement Location": "", @@ -1386,9 +1386,9 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "Waiting for zc vplan" + "High Priority?": "High Priority", + "Link to Coverage": "A: (SKIPPED).\n\nCOV: (SKIPPED).", + "Comment": "Assert and cover skipped in favor of trusting that formal will exercise the assert for pmp-specific cases." }, { "Requirement Location": "", @@ -1399,22 +1399,22 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "High Priority", "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "Waiting for clic vplan" + "Comment": "TODO Waiting for clic vplan" }, { "Requirement Location": "", "Feature": "Violations", "Sub Feature": "Priority", "Feature Description": "Exceptions priority apply to the PMP as well. Particularily, PMP exception (instruction access fault) gets priority over bus errors (instruction bus fault) if an instruction is the result of two fetches were both of these occurred.\n\nNote: Both could be present in an attempted executed instruction at the same time, because no exception occurs before the point of execution so there is enough time for both to be captured and travel through the pipeline.", - "Verification Goal": "Keep track of words fetched with bus error and with pmp execute denied, check retired instructions for a pc that overlaps two such fetches (cover both orders), ensure that \"instruction access fault\" is the taken exception.", + "Verification Goal": "1) Keep track of words fetched with bus error and with pmp execute denied,\n2) check retired instructions for a pc that overlaps two such fetches (cover both orders),\n3) ensure that \"instruction access fault\" is the taken exception.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???\n\nCOV: ???", - "Comment": "TODO missing assert\n\nTODO missing cover" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED).\n\nCOV: (SKIPPED).", + "Comment": "Assert and cover skipped because it would require support logic with an unreasonably low ROI, and we have other exceptions checking." }, { "Requirement Location": "", @@ -1425,9 +1425,9 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED).", + "Comment": "Assert skipped in favor of regarding the pmp and pma efforts themselves as sufficient." }, { "Requirement Location": "", @@ -1438,9 +1438,9 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED).", + "Comment": "Assert skipped in favor of regarding the pmp and pma efforts themselves as sufficient." }, { "Requirement Location": "", @@ -1451,9 +1451,9 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED).", + "Comment": "Assert skipped in favor of regarding the pmp and pma efforts themselves as sufficient." }, { "Requirement Location": "", @@ -1464,25 +1464,25 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED).", + "Comment": "Assert skipped in favor of regarding the pmp and pma efforts themselves as sufficient." }, { - "Requirement Location": "misc", - "Feature": "Misc", + "Requirement Location": "", + "Feature": "Pma", "Sub Feature": "DisallowDebug", - "Feature Description": "The PMP can deny usage of debug mode by setting up regions for dm_halt_addr and dm_exception_addr.", - "Verification Goal": "Set up pmp rules so all D-mode entries are blocked from execution, attempt to enter debug mode, ensure that nohing is executed in debug mode.", + "Feature Description": "\"As execution based debug is used, the Debug Module region, as defined by the DM_REGION_START and DM_REGION_END parameters, needs to support code execution, loads and stores when CV32E40S is in debug mode. In order to achieve this CV32E40S overrules the PMA and PMP settings for the Debug Module region when it is in debug mode (see Physical Memory Attribution (PMA) and Physical Memory Protection (PMP)).\"", + "Verification Goal": "Check that accesses to the DM region are never blocked.\n\nCover: access within range, would deny / allow.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Directed Non-Self-Checking", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "Waiting for ongoing spec changes to be resolved" + "High Priority?": "High Priority", + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_accept_only_legal\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.*.mpu_i.pmp.pmp_i.u_pmp_assert_lsu.gen_pmp_assert.a_deny_only_illegal\n\nCOV: (SKIPPED).", + "Comment": "Cover skipped in favor of trusting that formal will exercise the assert for dm region specific cases." }, { - "Requirement Location": "", + "Requirement Location": "misc", "Feature": "Misc", "Sub Feature": "40x", "Feature Description": "The 40x does not have PMP.", @@ -1490,7 +1490,7 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -1503,7 +1503,7 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -1516,7 +1516,7 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", "Coverage Method": "Assertion Coverage", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_*\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_*\n\n(Indirectly checked by those asserts)", "Comment": "" }, @@ -1525,13 +1525,13 @@ "Feature": "Misc", "Sub Feature": "RvfiTrap", "Feature Description": "The \"rvfi_trap\" table has PMP-specific fields.", - "Verification Goal": "Augment the exception checkers above with checking of \"rvfi_trap.cause_type\" to ensure that specifically PMP is reported as the cause.", + "Verification Goal": "Augment the exception checkers above with checking of \"rvfi_trap.cause_type\" to ensure that specifically PMP is reported as the cause.\nE.g. \"|-> rvfi_trap\" changed to \"|-> rvfi_trap && \".", "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_noexec_cause\".\n\nA: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_noloadstore_cause_load\".\n\nA: uvmt_cv32e40s_pmprvfi_assert.sv, \"a_noloadstore_cause_store\".", + "Comment": "" }, { "Requirement Location": "", @@ -1542,7 +1542,7 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "No", "Link to Coverage": "N/A", "Comment": "" }, @@ -1555,7 +1555,7 @@ "Pass/Fail Criteria": "N/A", "Test Type": "N/A", "Coverage Method": "N/A", - "High Priority?": "", + "High Priority?": "High Priority", "Link to Coverage": "N/A", "Comment": "" }, @@ -1568,151 +1568,34 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "No", + "Link to Coverage": "A: (SKIPPED).", + "Comment": "Skipped in favor of trusting \"WaitUpdate\" and \"AffectSuccessors\" and all other functional asserts.." }, { "Requirement Location": "", "Feature": "Misc", "Sub Feature": "UmodeZeroRegions", "Feature Description": "If the parameters are set to have 0 pmp regions, then all rules are OFF and U-mode matches nothing and defaults to not have any access.", - "Verification Goal": "Be in U-mode, have PMP_NUM_REGIONS=0, ensure all accesses fail (read/write/execute).", + "Verification Goal": "Be in U-mode, have PMP_NUM_REGIONS=0, ensure all accesses fail (read/write/execute).\n\nNote: also assert that read/write attempts can not occur.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Assertion Coverage", - "High Priority?": "", - "Link to Coverage": "A: ???", - "Comment": "TODO missing assert" + "High Priority?": "High Priority", + "Link to Coverage": "A: (SKIPPED).", + "Comment": "Skipped in favor of using realease-specific configs." }, { "Requirement Location": "debug", "Feature": "Mmode", "Sub Feature": "", "Feature Description": "\"All operations are executed with machine mode privilege\".\nIt is mostly the responsibility of other vplans to check D-mode relationship to M-mode and U-mode, but the pmp inputs should be checked against debug mode.\n\nNote: Refer to user-mode vplan and debug vplan if necessary.\n\nNote: It is assumed that once 1) dmode is shown to be interpreted as mmode by pmp, and 2) all mmode features are verified, then C) the mmode features will work in dmode. But one alternative is to duplicate all the mmode-related checking with dmode variants.", - "Verification Goal": "Ensure that the PMP inputs receive the correct mode while in D-mode.\n\nNote: Test w/wo MPRV too.", + "Verification Goal": "Ensure that the PMP inputs receive the correct mode while in D-mode.\n\nCover: w/wo MPRV.", "Pass/Fail Criteria": "Assertion Check", "Test Type": "Constrained-Random", "Coverage Method": "Functional Coverage", "High Priority?": "High Priority", - "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_*\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_*\n\n(Indirectly checked by those asserts, together with effective priv mode and umode asserts for dmode/mmode.)\n\nCOV: ???", - "Comment": "TODO missing cover" - }, - { - "Requirement Location": "", - "Feature": "Mmode", - "Sub Feature": "", - "Feature Description": "", - "Verification Goal": "Ensure that the PMP inputs receive the correct mode while in D-mode.\n\nNote: Test w/wo MPRV too.", - "Pass/Fail Criteria": "", - "Test Type": "", - "Coverage Method": "", - "High Priority?": "", - "Link to Coverage": "", - "Comment": "" - }, - { - "Requirement Location": "", - "Feature": "Mmode", - "Sub Feature": "", - "Feature Description": "", - "Verification Goal": "Ensure that the PMP inputs receive the correct mode while in D-mode.\n\nNote: Test w/wo MPRV too.", - "Pass/Fail Criteria": "", - "Test Type": "", - "Coverage Method": "", - "High Priority?": "", - "Link to Coverage": "", - "Comment": "" - }, - { - "Requirement Location": "", - "Feature": "Mmode", - "Sub Feature": "", - "Feature Description": "", - "Verification Goal": "Ensure that the PMP inputs receive the correct mode while in D-mode.\n\nNote: Test w/wo MPRV too.", - "Pass/Fail Criteria": "", - "Test Type": "", - "Coverage Method": "", - "High Priority?": "", - "Link to Coverage": "", - "Comment": "" - }, - { - "Requirement Location": "", - "Feature": "Mmode", - "Sub Feature": "", - "Feature Description": "", - "Verification Goal": "Ensure that the PMP inputs receive the correct mode while in D-mode.\n\nNote: Test w/wo MPRV too.", - "Pass/Fail Criteria": "", - "Test Type": "", - "Coverage Method": "", - "High Priority?": "", - "Link to Coverage": "", - "Comment": "" - }, - { - "Requirement Location": "", - "Feature": "Mmode", - "Sub Feature": "", - "Feature Description": "", - "Verification Goal": "Ensure that the PMP inputs receive the correct mode while in D-mode.\n\nNote: Test w/wo MPRV too.", - "Pass/Fail Criteria": "", - "Test Type": "", - "Coverage Method": "", - "High Priority?": "", - "Link to Coverage": "", - "Comment": "" - }, - { - "Requirement Location": "", - "Feature": "Mmode", - "Sub Feature": "", - "Feature Description": "", - "Verification Goal": "Ensure that the PMP inputs receive the correct mode while in D-mode.\n\nNote: Test w/wo MPRV too.", - "Pass/Fail Criteria": "", - "Test Type": "", - "Coverage Method": "", - "High Priority?": "", - "Link to Coverage": "", - "Comment": "" - }, - { - "Requirement Location": "", - "Feature": "Mmode", - "Sub Feature": "", - "Feature Description": "", - "Verification Goal": "Ensure that the PMP inputs receive the correct mode while in D-mode.\n\nNote: Test w/wo MPRV too.", - "Pass/Fail Criteria": "", - "Test Type": "", - "Coverage Method": "", - "High Priority?": "", - "Link to Coverage": "", - "Comment": "" - }, - { - "Requirement Location": "", - "Feature": "Mmode", - "Sub Feature": "", - "Feature Description": "", - "Verification Goal": "Ensure that the PMP inputs receive the correct mode while in D-mode.\n\nNote: Test w/wo MPRV too.", - "Pass/Fail Criteria": "", - "Test Type": "", - "Coverage Method": "", - "High Priority?": "", - "Link to Coverage": "", - "Comment": "" - }, - { - "Requirement Location": " -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- END -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------", - "Feature": "Mmode", - "Sub Feature": "", - "Feature Description": "", - "Verification Goal": "Ensure that the PMP inputs receive the correct mode while in D-mode.\n\nNote: Test w/wo MPRV too.", - "Pass/Fail Criteria": "", - "Test Type": "", - "Coverage Method": "", - "High Priority?": "", - "Link to Coverage": "", - "Comment": "" + "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noexec_*\n\nA: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.rvfi_i.pmprvfi_assert_i.a_noloadstore_*\n\n(Indirectly checked by those asserts, together with effective priv mode and umode asserts for dmode/mmode.)\n\nCOV: (SKIPPED).", + "Comment": "Cover skipped because the asserts are deemed sufficient, and because debug has its own new override mechanism." } ] \ No newline at end of file diff --git a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.xlsx b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.xlsx index a24e24418a..c52977586c 100755 Binary files a/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.xlsx and b/cv32e40s/docs/VerifPlans/Simulation/privileged_spec/CV32E40S_PMP.xlsx differ diff --git a/cv32e40s/env/corev-dv/cv32e40s_asm_program_gen.sv b/cv32e40s/env/corev-dv/cv32e40s_asm_program_gen.sv index 9d1f1a9107..6e3210808e 100644 --- a/cv32e40s/env/corev-dv/cv32e40s_asm_program_gen.sv +++ b/cv32e40s/env/corev-dv/cv32e40s_asm_program_gen.sv @@ -19,17 +19,19 @@ //----------------------------------------------------------------------------------------- // CV32E40S CORE-V assembly program generator - extension of the RISC-V assembly program generator. // -// Overrides gen_program_header() and gen_test_done() +// Overrides gen_program_header() and gen_test_done() and other riscv-dv functions. //----------------------------------------------------------------------------------------- class cv32e40s_asm_program_gen extends corev_asm_program_gen; `uvm_object_utils(cv32e40s_asm_program_gen) + function new (string name = ""); super.new(name); endfunction + virtual function void gen_program_header(); string instr[]; cv32e40s_instr_gen_config corev_cfg; @@ -99,6 +101,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; endfunction : gen_program_header + virtual function void trap_vector_init(int hart); string instr[]; privileged_reg_t trap_vec_reg; @@ -153,6 +156,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("trap_vec_init", hart), instr); endfunction : trap_vector_init + virtual function void gen_illegal_instr_handler(int hart); string instr[$]; string load_instr = (XLEN == 32) ? "lw" : "ld"; @@ -195,6 +199,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("illegal_instr_handler", hart), instr); endfunction + virtual function void gen_instr_fault_handler(int hart); string instr[$]; string load_instr = (XLEN == 32) ? "lw" : "ld"; @@ -232,6 +237,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("instr_fault_handler", hart), instr); endfunction + // TODO: handshake correct csr based on delegation virtual function void gen_load_fault_handler(int hart); string instr[$]; @@ -253,6 +259,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("load_fault_handler", hart), instr); endfunction + // TODO: handshake correct csr based on delegation virtual function void gen_store_fault_handler(int hart); string instr[$]; @@ -273,6 +280,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("store_fault_handler", hart), instr); endfunction + virtual function void gen_interrupt_vector_table(int hart, string mode, privileged_reg_t status, @@ -344,6 +352,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; end endfunction : gen_interrupt_vector_table + // Setup EPC before entering target privileged mode virtual function void setup_epc(int hart); string instr[$]; @@ -362,6 +371,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("mepc_setup", hart), instr); endfunction + // Interrupt handler routine // Override from risc-dv: // 1. Remove MIP read, since interrupts are auto-cleared, mip will not track through the ISS @@ -516,6 +526,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; endfunction : gen_interrupt_handler_section + // Override gen_stack_section to add debugger stack generation section // Implmeneted as a post-step to super.gen_stack_section() virtual function void gen_stack_section(int hart); @@ -535,6 +546,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; endfunction : gen_stack_section + // Override of init_gpr to remove cfg.dp from initiailization if a debug section is generated virtual function void init_gpr(); string str; @@ -560,6 +572,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; end endfunction + // generate NMI handler. // will be placed at a fixed address in memory, set in linker file virtual function void gen_nmi_handler_section(int hart); @@ -587,8 +600,10 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; nmi_handler_instr); endfunction : gen_nmi_handler_section + virtual function void gen_section(string label, string instr[$]); string str; + if(label == "mtvec_handler" && cfg.mtvec_mode == VECTORED) begin str = ".section .mtvec_handler, \"ax\""; instr_stream.push_back(str); @@ -598,6 +613,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; str = format_string($sformatf("%0s:", label), LABEL_STR_LEN); instr_stream.push_back(str); end + foreach(instr[i]) begin str = {indent, instr[i]}; instr_stream.push_back(str); @@ -607,7 +623,25 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; instr_stream.push_back(str); end end + instr_stream.push_back(""); endfunction : gen_section + + virtual function void gen_init_section(int hart); + string instrs[]; + string label; + + super.gen_init_section(hart); + + // After the "init" section, bus errors can safely occur without havoc + label = get_label("obi_err_goahead", hart); + instrs = { + $sformatf("li x%0d, 0x%08x", cfg.gpr[0], CV_VP_OBI_ERR_AWAIT_GOAHEAD_BASE), + $sformatf("sw x0, 0(x%0d)", cfg.gpr[0]) + }; + gen_section(label, instrs); + endfunction + + endclass : cv32e40s_asm_program_gen diff --git a/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv b/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv index 48804c2db2..e6172209ce 100644 --- a/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv +++ b/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv @@ -28,18 +28,20 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c; // Integrals rand int unsigned sys_clk_period; cv32e40s_pkg::b_ext_e b_ext; - bit obi_memory_instr_random_err_enabled = 0; - bit obi_memory_instr_one_shot_err_enabled = 0; - bit obi_memory_data_random_err_enabled = 0; - bit obi_memory_data_one_shot_err_enabled = 0; - bit iss_suppress_invalid_msg = 0; - bit nmi_timeout_instr_plusarg_valid = 0; - bit irq_min_limit_plusarg_valid = 0; - bit single_step_min_limit_plusarg_valid = 0; - bit irq_single_step_threshold_plusarg_valid = 0; - bit clic_irq_clear_on_ack_plusarg_valid = 0; + bit obi_memory_data_one_shot_err_enabled = 0; + bit obi_memory_data_random_err_await_goahead = 0; + bit obi_memory_data_random_err_enabled = 0; + bit obi_memory_instr_one_shot_err_enabled = 0; + bit obi_memory_instr_random_err_await_goahead = 0; + bit obi_memory_instr_random_err_enabled = 0; + bit iss_suppress_invalid_msg = 0; + bit nmi_timeout_instr_plusarg_valid = 0; + bit irq_min_limit_plusarg_valid = 0; + bit single_step_min_limit_plusarg_valid = 0; + bit irq_single_step_threshold_plusarg_valid = 0; + bit clic_irq_clear_on_ack_plusarg_valid = 0; rand bit clic_irq_clear_on_ack; - rand bit buserr_scoreboarding_enabled = 1; + rand bit buserr_scoreboarding_enabled = 1; rand int unsigned fetch_toggle_initial_delay; rand int unsigned nmi_timeout_instr; rand int unsigned single_step_min_limit; @@ -60,23 +62,25 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c; rand uvma_pma_cfg_c#(ILEN,XLEN) pma_cfg; `uvm_object_utils_begin(uvme_cv32e40s_cfg_c) - `uvm_field_int ( enabled, UVM_DEFAULT ) - `uvm_field_enum(uvm_active_passive_enum, is_active, UVM_DEFAULT ) - `uvm_field_int ( cov_model_enabled, UVM_DEFAULT ) - `uvm_field_int ( trn_log_enabled, UVM_DEFAULT ) - `uvm_field_int ( buserr_scoreboarding_enabled, UVM_DEFAULT ) - `uvm_field_int ( sys_clk_period, UVM_DEFAULT | UVM_DEC ) - `uvm_field_enum (b_ext_e, b_ext, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_instr_random_err_enabled, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_instr_one_shot_err_enabled, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_data_random_err_enabled, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_data_one_shot_err_enabled, UVM_DEFAULT ) - `uvm_field_int ( iss_suppress_invalid_msg, UVM_DEFAULT ) - `uvm_field_int ( fetch_toggle_initial_delay, UVM_DEFAULT ) - `uvm_field_int ( nmi_timeout_instr, UVM_DEFAULT | UVM_DEC ) - `uvm_field_int ( single_step_min_limit, UVM_DEFAULT | UVM_DEC ) - `uvm_field_int ( irq_min_limit, UVM_DEFAULT | UVM_DEC ) - `uvm_field_int ( irq_single_step_threshold, UVM_DEFAULT | UVM_DEC ) + `uvm_field_int ( enabled, UVM_DEFAULT ) + `uvm_field_enum(uvm_active_passive_enum, is_active, UVM_DEFAULT ) + `uvm_field_int ( cov_model_enabled, UVM_DEFAULT ) + `uvm_field_int ( trn_log_enabled, UVM_DEFAULT ) + `uvm_field_int ( buserr_scoreboarding_enabled, UVM_DEFAULT ) + `uvm_field_int ( sys_clk_period, UVM_DEFAULT | UVM_DEC ) + `uvm_field_enum(b_ext_e, b_ext, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_data_one_shot_err_enabled, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_data_random_err_await_goahead, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_data_random_err_enabled, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_instr_one_shot_err_enabled, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_instr_random_err_await_goahead,UVM_DEFAULT ) + `uvm_field_int ( obi_memory_instr_random_err_enabled, UVM_DEFAULT ) + `uvm_field_int ( iss_suppress_invalid_msg, UVM_DEFAULT ) + `uvm_field_int ( fetch_toggle_initial_delay, UVM_DEFAULT ) + `uvm_field_int ( nmi_timeout_instr, UVM_DEFAULT | UVM_DEC ) + `uvm_field_int ( single_step_min_limit, UVM_DEFAULT | UVM_DEC ) + `uvm_field_int ( irq_min_limit, UVM_DEFAULT | UVM_DEC ) + `uvm_field_int ( irq_single_step_threshold, UVM_DEFAULT | UVM_DEC ) `uvm_field_object(isacov_cfg , UVM_DEFAULT) `uvm_field_object(clknrst_cfg , UVM_DEFAULT) @@ -333,6 +337,19 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c; obi_memory_data_cfg.drv_slv_err_one_shot_mode == obi_memory_data_one_shot_err_enabled; } + + constraint obi_memory_data_random_err_await_goahead_cons { + if (obi_memory_data_random_err_await_goahead) { + obi_memory_data_cfg.random_err_await_goahead == 1; + } + } + + constraint obi_memory_instr_random_err_await_goahead_cons { + if (obi_memory_instr_random_err_await_goahead) { + obi_memory_instr_cfg.random_err_await_goahead == 1; + } + } + /** * Creates sub-configuration objects. */ @@ -370,19 +387,25 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c; endclass : uvme_cv32e40s_cfg_c + function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg"); super.new(name); core_name = "CV32E40S"; + + // Read Plusargs + if ($test$plusargs("USE_ISS")) begin use_iss = 1; end + if ($test$plusargs("trn_log_disabled")) begin trn_log_enabled = 0; trn_log_enabled.rand_mode(0); end + if ($test$plusargs("buserr_sb_disabled")) begin buserr_scoreboarding_enabled = 0; buserr_scoreboarding_enabled.rand_mode(0); @@ -391,27 +414,42 @@ function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg"); if ($test$plusargs("obi_memory_instr_random_err")) begin obi_memory_instr_random_err_enabled = 1; end + if ($test$plusargs("obi_memory_instr_one_shot_err")) begin obi_memory_instr_one_shot_err_enabled = 1; end + if ($test$plusargs("obi_memory_data_random_err")) begin obi_memory_data_random_err_enabled = 1; end + + if ($test$plusargs("obi_memory_data_random_err_await_goahead")) begin + obi_memory_data_random_err_await_goahead = 1; + end + + if ($test$plusargs("obi_memory_instr_random_err_await_goahead")) begin + obi_memory_instr_random_err_await_goahead = 1; + end + if ($test$plusargs("obi_memory_data_one_shot_err")) begin obi_memory_data_one_shot_err_enabled = 1; end + if ($value$plusargs("nmi_timeout_instr=%d", nmi_timeout_instr)) begin nmi_timeout_instr_plusarg_valid = 1; nmi_timeout_instr.rand_mode(0); end + if ($value$plusargs("irq_single_step_threshold=%0d", irq_single_step_threshold)) begin irq_single_step_threshold_plusarg_valid = 1; irq_single_step_threshold.rand_mode(0); end + if ($value$plusargs("irq_min_limit=%0d", irq_min_limit)) begin irq_min_limit_plusarg_valid = 1; irq_min_limit.rand_mode(0); end + if ($value$plusargs("single_step_min_limit=%0d", single_step_min_limit)) begin single_step_min_limit_plusarg_valid = 1; single_step_min_limit.rand_mode(0); @@ -428,6 +466,8 @@ function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg"); end + // Create Configs + isacov_cfg = uvma_isacov_cfg_c::type_id::create("isacov_cfg"); clknrst_cfg = uvma_clknrst_cfg_c::type_id::create("clknrst_cfg"); interrupt_cfg = uvma_interrupt_cfg_c::type_id::create("interrupt_cfg"); @@ -441,6 +481,8 @@ function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg"); pma_cfg = uvma_pma_cfg_c#(ILEN,XLEN)::type_id::create("pma_cfg"); + // Assign loggers and configs + obi_memory_instr_cfg.mon_logger_name = "OBII"; obi_memory_data_cfg.mon_logger_name = "OBID"; @@ -449,12 +491,14 @@ function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg"); endfunction : new + function void uvme_cv32e40s_cfg_c::pre_randomize(); `uvm_info("CFG", $sformatf("Pre-randomize num_mhpmcounters = %0d", num_mhpmcounters), UVM_LOW); endfunction : pre_randomize + function void uvme_cv32e40s_cfg_c::post_randomize(); super.post_randomize(); diff --git a/cv32e40s/env/uvme/uvme_cv32e40s_env.sv b/cv32e40s/env/uvme/uvme_cv32e40s_env.sv index caf1983d17..9a7f83cf89 100644 --- a/cv32e40s/env/uvme/uvme_cv32e40s_env.sv +++ b/cv32e40s/env/uvme/uvme_cv32e40s_env.sv @@ -760,6 +760,37 @@ function void uvme_cv32e40s_env_c::install_vp_register_seqs(uvma_obi_memory_slv_ vp_seq.cv32e40s_cntxt = cntxt; end + begin + uvma_obi_memory_vp_base_seq_c#( + .ACHK_WIDTH (ENV_PARAM_DATA_ACHK_WIDTH), + .ADDR_WIDTH (ENV_PARAM_DATA_ADDR_WIDTH), + .AUSER_WIDTH (ENV_PARAM_DATA_AUSER_WIDTH), + .DATA_WIDTH (ENV_PARAM_DATA_DATA_WIDTH), + .ID_WIDTH (ENV_PARAM_DATA_ID_WIDTH), + .RCHK_WIDTH (ENV_PARAM_DATA_RCHK_WIDTH), + .RUSER_WIDTH (ENV_PARAM_DATA_RUSER_WIDTH), + .WUSER_WIDTH (ENV_PARAM_DATA_WUSER_WIDTH) + ) new_created_base_seq; + + uvme_cv32e40s_vp_obi_err_await_goahead_seq_c casted_seq_handle; + + new_created_base_seq = data_slv_seq.register_vp_vseq( + "vp_obi_err_await_goahead", + CV_VP_OBI_ERR_AWAIT_GOAHEAD_BASE, + uvme_cv32e40s_vp_obi_err_await_goahead_seq_c::get_type() + ); + + if (!$cast(casted_seq_handle, new_created_base_seq)) begin + `uvm_fatal( + "CV32E40SVPSEQ", + $sformatf("Could not cast/assign vp_obi_err_await_goahead") + ); + end + + casted_seq_handle.obi_memory_cfg_instr = cfg.obi_memory_instr_cfg; + casted_seq_handle.obi_memory_cfg_data = cfg.obi_memory_data_cfg; + end + endfunction : install_vp_register_seqs `endif // __UVME_CV32E40S_ENV_SV__ diff --git a/cv32e40s/env/uvme/uvme_cv32e40s_pkg.sv b/cv32e40s/env/uvme/uvme_cv32e40s_pkg.sv index 6134e59ee0..cc0ef42b06 100644 --- a/cv32e40s/env/uvme/uvme_cv32e40s_pkg.sv +++ b/cv32e40s/env/uvme/uvme_cv32e40s_pkg.sv @@ -74,10 +74,11 @@ package uvme_cv32e40s_pkg; `include "uvme_cv32e40s_nmi_timeout_vseq.sv" `include "uvme_cv32e40s_irq_ss_timeout_vseq.sv" `include "uvme_cv32e40s_vp_debug_control_seq.sv" + `include "uvme_cv32e40s_vp_fencei_tamper_seq.sv" `include "uvme_cv32e40s_vp_interrupt_timer_seq.sv" + `include "uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv" `include "uvme_cv32e40s_vp_sig_writer_seq.sv" `include "uvme_cv32e40s_vp_status_flags_seq.sv" - `include "uvme_cv32e40s_vp_fencei_tamper_seq.sv" `include "uvme_cv32e40s_interrupt_noise_vseq.sv" `include "uvme_cv32e40s_clic_noise_vseq.sv" `include "uvme_cv32e40s_vseq_lib.sv" diff --git a/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_fencei_tamper_seq.sv b/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_fencei_tamper_seq.sv index 24c00186e1..5924eeefb9 100644 --- a/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_fencei_tamper_seq.sv +++ b/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_fencei_tamper_seq.sv @@ -40,7 +40,7 @@ class uvme_cv32e40s_vp_fencei_tamper_seq_c#( .RCHK_WIDTH(RCHK_WIDTH) ); - uvme_cv32e40s_cntxt_c cv32e40s_cntxt; + uvme_cv32e40s_cntxt_c cv32e40s_cntxt; bit enabled = 0; bit [31:0] addr; diff --git a/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv b/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv new file mode 100644 index 0000000000..8acbc0606b --- /dev/null +++ b/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv @@ -0,0 +1,59 @@ +// Copyright 2023 Silicon Labs, Inc. +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may +// not use this file except in compliance with the License, or, at your option, +// the Apache License version 2.0. +// +// You may obtain a copy of the License at +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// 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. + + +class uvme_cv32e40s_vp_obi_err_await_goahead_seq_c + extends uvma_obi_memory_vp_base_seq_c #( + .AUSER_WIDTH (ENV_PARAM_DATA_AUSER_WIDTH), + .WUSER_WIDTH (ENV_PARAM_DATA_WUSER_WIDTH), + .RUSER_WIDTH (ENV_PARAM_DATA_RUSER_WIDTH), + .ADDR_WIDTH (ENV_PARAM_DATA_ADDR_WIDTH), + .DATA_WIDTH (ENV_PARAM_DATA_DATA_WIDTH), + .ID_WIDTH (ENV_PARAM_DATA_ID_WIDTH), + .ACHK_WIDTH (ENV_PARAM_DATA_ACHK_WIDTH), + .RCHK_WIDTH (ENV_PARAM_DATA_RCHK_WIDTH) + ); + + `uvm_object_utils( uvme_cv32e40s_vp_obi_err_await_goahead_seq_c ) + + uvma_obi_memory_cfg_c obi_memory_cfg_instr; + uvma_obi_memory_cfg_c obi_memory_cfg_data; + + + function new(string name="uvme_cv32e40s_vp_obi_err_await_goahead_seq_c"); + super.new(name); + endfunction + + + function int unsigned get_num_words(); + return 1; + endfunction + + + virtual task vp_body(uvma_obi_memory_mon_trn_c mon_trn); + uvma_obi_memory_slv_seq_item_c slv_rsp; + + obi_memory_cfg_instr.random_err_await_goahead = 0; + obi_memory_cfg_data.random_err_await_goahead = 0; + + `uvm_create(slv_rsp) + `uvm_send(slv_rsp) + endtask + + +endclass diff --git a/cv32e40s/regress/cv32e40s_full.yaml b/cv32e40s/regress/cv32e40s_full.yaml index 66ba231d96..97184ca53b 100644 --- a/cv32e40s/regress/cv32e40s_full.yaml +++ b/cv32e40s/regress/cv32e40s_full.yaml @@ -576,3 +576,16 @@ tests: builds: [ uvmt_cv32e40s_clic ] dir: cv32e40s/sim/uvmt cmd: make test TEST=zcmt_test + + mhpmcounter_write_test: + description: test writing to mhpm counters + builds: [ uvmt_cv32e40s_clic ] + dir: cv32e40s/sim/uvmt + cmd: make test TEST=mhpmcounter_write_test + + minhv_pma_block: + description: test minhv=1 and pma block of mepc address + builds: [ uvmt_cv32e40s_pma_2 ] + dir: cv32e40s/sim/uvmt + cmd: make test TEST=minhv_pma_block + diff --git a/cv32e40s/sim/ExternalRepos.mk b/cv32e40s/sim/ExternalRepos.mk index d2cb18a691..edd513e9f3 100644 --- a/cv32e40s/sim/ExternalRepos.mk +++ b/cv32e40s/sim/ExternalRepos.mk @@ -15,7 +15,7 @@ export SHELL = /bin/bash CV_CORE_REPO ?= https://github.com/openhwgroup/cv32e40s CV_CORE_BRANCH ?= master -CV_CORE_HASH ?= 61e1535c8d5e3086a88cc03dc8d984ba274b81f0 +CV_CORE_HASH ?= 04947655f5642821f78904f8feb13dd677fbcc6d CV_CORE_TAG ?= none #RISCVDV_REPO ?= https://github.com/google/riscv-dv diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_pmp_assert.sv b/cv32e40s/tb/assertions/uvmt_cv32e40s_pmp_assert.sv similarity index 97% rename from cv32e40s/tb/uvmt/uvmt_cv32e40s_pmp_assert.sv rename to cv32e40s/tb/assertions/uvmt_cv32e40s_pmp_assert.sv index 52b14563fc..ef9abfa5e9 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_pmp_assert.sv +++ b/cv32e40s/tb/assertions/uvmt_cv32e40s_pmp_assert.sv @@ -205,25 +205,25 @@ module uvmt_cv32e40s_pmp_assert iff (csr_pmp_i.cfg[match_status.val_index].mode == PMP_MODE_NAPOT && match_status.is_matched == 1'b1 && match_status.is_access_allowed == 1'b1 - ); + ); cp_napot_min_8byte_disallowed: coverpoint { pmp_req_addr_i[2+PMP_GRANULARITY], csr_pmp_i.addr[match_status.val_index][2+PMP_GRANULARITY] } iff (csr_pmp_i.cfg[match_status.val_index].mode == PMP_MODE_NAPOT && match_status.is_matched == 1'b1 && match_status.is_access_allowed == 1'b0 - ); + ); cp_napot_encoding: coverpoint ( pmp_req_addr_i[33:2+PMP_GRANULARITY] == csr_pmp_i.addr[match_status.val_index][33:2+PMP_GRANULARITY] ) iff (csr_pmp_i.cfg[match_status.val_index].mode == PMP_MODE_NAPOT && match_status.is_matched == 1'b1 && match_status.is_access_allowed == 1'b1 - ); + ); cp_napot_encoding_disallowed: coverpoint ( pmp_req_addr_i[33:2+PMP_GRANULARITY] == csr_pmp_i.addr[match_status.val_index][33:2+PMP_GRANULARITY] ) iff (csr_pmp_i.cfg[match_status.val_index].mode == PMP_MODE_NAPOT && match_status.is_matched == 1'b1 && match_status.is_access_allowed == 1'b0 - ); + ); endgroup cg_internals_common cg_int = new(); @@ -306,6 +306,14 @@ module uvmt_cv32e40s_pmp_assert $changed(csr_pmp_i.cfg[region].read) ); + if (region > 0) begin: gen_tor + cov_rlb_locked_rules_can_modify_tor : cover property ( + csr_pmp_i.mseccfg.rlb === 1'b1 && csr_pmp_i.cfg[region].lock === 1'b1 && + csr_pmp_i.cfg[region].mode === PMP_MODE_TOR ##1 + $changed(csr_pmp_i.cfg[region-1]) + ); + end + cov_rlb_locked_rules_can_remove : cover property ( csr_pmp_i.mseccfg.rlb === 1'b1 && csr_pmp_i.cfg[region].lock == 1'b1 && @@ -538,6 +546,23 @@ module uvmt_cv32e40s_pmp_assert end + // "mseccfg" has fields hardwired to 0 (vplan:ReservedZero) + + a_reserved_zero_mseccfg_fields: assert property ( + csr_pmp_i.mseccfg[31:3] == '0 + ) else `uvm_error(info_tag, "mseccfg fields not zero"); + + + // "Unused" PMP CSRs read as zero (vplan:UnusedZero) + + for (genvar i = PMP_NUM_REGIONS; i < 64; i++) begin: gen_unused_zero + a_unused_zero_pmp_csrs: assert property ( + csr_pmp_i.cfg[i] == '0 && + csr_pmp_i.addr[i] == '0 + ); + end + + endmodule : uvmt_cv32e40s_pmp_assert diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_pmprvfi_assert.sv b/cv32e40s/tb/assertions/uvmt_cv32e40s_pmprvfi_assert.sv similarity index 88% rename from cv32e40s/tb/uvmt/uvmt_cv32e40s_pmprvfi_assert.sv rename to cv32e40s/tb/assertions/uvmt_cv32e40s_pmprvfi_assert.sv index 7384639c0b..6feea9569c 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_pmprvfi_assert.sv +++ b/cv32e40s/tb/assertions/uvmt_cv32e40s_pmprvfi_assert.sv @@ -23,14 +23,15 @@ module uvmt_cv32e40s_pmprvfi_assert import cv32e40s_pkg::*; import support_pkg::*; + import isa_decoder_pkg::*; import uvm_pkg::*; import uvma_rvfi_pkg::*; import uvma_rvfi_pkg::EXC_CAUSE_INSTR_BUS_FAULT; import uvma_rvfi_pkg::EXC_CAUSE_INSTR_INTEGRITY_FAULT; import uvmt_cv32e40s_base_test_pkg::*; #( - parameter int PMP_GRANULARITY = 0, - parameter int PMP_NUM_REGIONS = 0 + parameter int PMP_GRANULARITY, + parameter int PMP_NUM_REGIONS )( // Clock and Reset input wire clk_i, @@ -38,6 +39,7 @@ module uvmt_cv32e40s_pmprvfi_assert //RVFI INSTR IF uvma_rvfi_instr_if_t rvfi_if, + uvmt_cv32e40s_support_logic_module_o_if_t.slave_mp support_if, // RVFI input wire rvfi_valid, input wire [31:0] rvfi_insn, @@ -84,14 +86,14 @@ module uvmt_cv32e40s_pmprvfi_assert string info_tag = "CV32E40S_PMPRVFI_ASSERT"; - localparam logic [1:0] MODE_U = 2'b 00; - localparam logic [1:0] MODE_M = 2'b 11; - localparam logic [2:0] DBG_TRIGGER = 3'd 2; - localparam int NUM_CFG_REGS = 16; - localparam int NUM_ADDR_REGS = 64; - localparam int CSRADDR_FIRST_PMPCFG = 12'h 3A0; - localparam int CSRADDR_FIRST_PMPADDR = 12'h 3B0; - localparam int CSRADDR_MSECCFG = 12'h 747; + localparam int NUM_ADDR_REGS = 64; + localparam int NUM_CFG_REGS = 16; + localparam logic [11:0] CSRADDR_FIRST_PMPADDR = 12'h 3B0; + localparam logic [11:0] CSRADDR_FIRST_PMPCFG = 12'h 3A0; + localparam logic [11:0] CSRADDR_MSECCFG = 12'h 747; + localparam logic [1:0] MODE_M = 2'b 11; + localparam logic [1:0] MODE_U = 2'b 00; + localparam logic [2:0] DBG_TRIGGER = 3'd 2; typedef struct packed { logic pc_lower; @@ -146,7 +148,7 @@ module uvmt_cv32e40s_pmprvfi_assert wire is_rvfi_csr_write_instr = is_rvfi_csr_instr && - !((rvfi_insn[13:12] inside {2'b 10, 2'b 11}) && !rvfi_rs1_addr); // CSRRS/C[I] w/ rs1=x0/0 + !((rvfi_insn[13:12] inside {2'b 01, 2'b 10, 2'b 11}) && !rvfi_rs1_addr); // CSRRW/S/C[I] w/ rs1=x0/0 wire [1:0] rvfi_effective_mode = rvfi_csr_mstatus_rdata[17] ? // "mstatus.MPRV", modify privilege? @@ -222,6 +224,16 @@ module uvmt_cv32e40s_pmprvfi_assert assign pmp_csr_rvfi_wdata.mseccfg = rvfi_csr_mseccfg_wdata; assign pmp_csr_rvfi_wmask.mseccfg = rvfi_csr_mseccfg_wmask; + logic is_all_regions_off; + always_comb begin + is_all_regions_off = 1; + for (int i = 0; i < PMP_NUM_REGIONS; i++) begin + if (pmp_csr_rvfi_rdata.cfg[i].mode != '0) begin + is_all_regions_off = 0; + end + end + end + // Helper models @@ -336,30 +348,22 @@ module uvmt_cv32e40s_pmprvfi_assert .* ); - var [31:0] clk_cnt; - always @(posedge clk_i, negedge rst_ni) begin - if (rst_ni == 0) begin - clk_cnt <= 32'd 1; - end else if (clk_cnt != '1) begin - clk_cnt <= clk_cnt + 32'd 1; - end - end // Assertions: - // PMP CSRs only accessible from M-mode (vplan:Csrs:MmodeOnly) + // PMP CSRs only accessible from M-mode (vplan:Csrs:MmodeOnly, vplan:MsecCfg:MmodeOnly) - sequence seq_csrs_mmode_only_ante; + sequence seq_pmp_csr_access(mode); is_rvfi_csr_instr && - (rvfi_mode == MODE_U) && + (rvfi_mode == mode) && (rvfi_insn[31:20] inside {['h3A0 : 'h3EF], 'h747, 'h757}) //PMP regs ; - endsequence : seq_csrs_mmode_only_ante + endsequence a_csrs_mmode_only: assert property ( - seq_csrs_mmode_only_ante + seq_pmp_csr_access(MODE_U) |-> is_rvfi_exc_ill_instr || is_rvfi_exc_instr_bus_fault || @@ -370,9 +374,16 @@ module uvmt_cv32e40s_pmprvfi_assert cov_csrs_mmode_only: cover property ( // Want to see "the real cause" (ill exc) finishing this property - seq_csrs_mmode_only_ante ##0 is_rvfi_exc_ill_instr + seq_pmp_csr_access(MODE_U) ##0 is_rvfi_exc_ill_instr ); + // M-mode can always access the csrs (vplan:AlwaysAccessible) + a_always_accessible_mmode_csrs: assert property ( + seq_pmp_csr_access(MODE_M) + |-> + ! is_rvfi_exc_ill_instr + ) else `uvm_error(info_tag, "mmode couldn't access csr"); + // NAPOT, some bits read as ones, depending on G (vplan:NapotOnes) @@ -498,26 +509,84 @@ module uvmt_cv32e40s_pmprvfi_assert // Stickiness isn't effectuated before triggered (vplan:LockingBypass:UntilReset) + logic first_MSECCFG_access; + + always @(posedge clk_i, negedge rst_ni) begin + if (rst_ni == 0) begin + first_MSECCFG_access <= 1'b 1; + end else if ( + rvfi_valid && + !rvfi_trap && + (support_if.asm_rvfi.instr == CSRRW || + support_if.asm_rvfi.instr == CSRRS || + support_if.asm_rvfi.instr == CSRRC || + support_if.asm_rvfi.instr == CSRRWI || + support_if.asm_rvfi.instr == CSRRSI || + support_if.asm_rvfi.instr == CSRRCI) + ) begin + first_MSECCFG_access <= 1'b 0; + end + end - property p_until_reset_notbefore(logic rlb); - $rose(rst_ni) ##0 - (rvfi_valid [->1]) ##0 // First retire - (is_rvfi_csr_write_instr && (rvfi_insn[14:12] == 3'b 001)) ##0 // ..."csrrw" - (rvfi_insn[31:20] == CSRADDR_MSECCFG) ##0 // ...to mseccfg - !rvfi_trap ##0 - (rvfi_rs1_rdata[2] == rlb) // (Write-attempt's data) - |-> - pmp_csr_rvfi_wmask.mseccfg.rlb && // Must attempt - (pmp_csr_rvfi_wdata.mseccfg.rlb == rlb) // Must succeed - ; - endproperty : p_until_reset_notbefore a_until_reset_notbefore_0: assert property ( - p_until_reset_notbefore(1'b 0) + + // First write access to MSECCFG: + (rvfi_valid && + first_MSECCFG_access && + + support_if.asm_rvfi.csr.address == MSECCFG && + support_if.asm_rvfi.csr.valid && + + (support_if.asm_rvfi.instr == CSRRW || + support_if.asm_rvfi.instr == CSRRC || + support_if.asm_rvfi.instr == CSRRWI || + support_if.asm_rvfi.instr == CSRRCI) && + + !rvfi_trap) + + ##0 + + // Set RLB bit to 0: + ((support_if.asm_rvfi.instr == CSRRW && rvfi_rs1_rdata[2] == 1'b0) || + (support_if.asm_rvfi.instr == CSRRC && rvfi_rs1_rdata[2] == 1'b1) || + (support_if.asm_rvfi.instr == CSRRWI && support_if.asm_rvfi.imm.imm_value[2] == 1'b0) || + (support_if.asm_rvfi.instr == CSRRCI && support_if.asm_rvfi.imm.imm_value[2] == 1'b1)) + + |-> + pmp_csr_rvfi_wmask.mseccfg.rlb && // Must attempt + (pmp_csr_rvfi_wdata.mseccfg.rlb == 1'b0) // Must succeed ) else `uvm_error(info_tag, "RLB must be changeable after reset"); + a_until_reset_notbefore_1: assert property ( - p_until_reset_notbefore(1'b 1) + + // First write access to MSECCFG: + (rvfi_valid && + first_MSECCFG_access && + + support_if.asm_rvfi.csr.address == MSECCFG && + support_if.asm_rvfi.csr.valid && + + (support_if.asm_rvfi.instr == CSRRW || + support_if.asm_rvfi.instr == CSRRS || + support_if.asm_rvfi.instr == CSRRWI || + support_if.asm_rvfi.instr == CSRRSI) && + + !rvfi_trap) + + ##0 + + // Set RLB bit to 1: + ((support_if.asm_rvfi.instr == CSRRW || support_if.asm_rvfi.instr == CSRRS) && + rvfi_rs1_rdata[2] == 1'b1) || + + ((support_if.asm_rvfi.instr == CSRRWI || support_if.asm_rvfi.instr == CSRRSI) && + support_if.asm_rvfi.imm.imm_value[2]) + + |-> + pmp_csr_rvfi_wmask.mseccfg.rlb && // Must attempt + (pmp_csr_rvfi_wdata.mseccfg.rlb == 1'b1) // Must succeed ) else `uvm_error(info_tag, "RLB must be changeable after reset"); @@ -897,7 +966,7 @@ module uvmt_cv32e40s_pmprvfi_assert csr_intended_wdata <= rvfi_if.csr_intended_wdata( ({24'd 0, pmp_csr_rvfi_rdata.cfg[i]} << 8*(i%4)), - (CSRADDR_FIRST_PMPCFG + (i / 3'd4)) + (CSRADDR_FIRST_PMPCFG + (i[11:0] / 3'd4)) ); end wire pmpncfg_t cfg_attempt = csr_intended_wdata[32'd 8 * (i%4) +: 8]; @@ -906,7 +975,7 @@ module uvmt_cv32e40s_pmprvfi_assert pmp_csr_rvfi_rdata.mseccfg.rlb && pmp_csr_rvfi_rdata.mseccfg.mml ##0 - rvfi_if.is_csr_write(CSRADDR_FIRST_PMPCFG + (i / 3'd4)) && + rvfi_if.is_csr_write(CSRADDR_FIRST_PMPCFG + (i[11:0] / 3'd4)) && !rvfi_trap && !(PMP_GRANULARITY > 0 && cfg_attempt.mode == PMP_MODE_NA4) ; @@ -928,6 +997,23 @@ module uvmt_cv32e40s_pmprvfi_assert ); + // If all regions "OFF", U-mode fails (vplan:UmodeOff) + + a_umode_off: assert property ( + rvfi_if.is_umode && + is_all_regions_off + |-> + rvfi_if.rvfi_trap + ); + + + // "mseccfgh" is just zero (vplan:MseccfghZero) + + a_mseccfgh_zero: assert property ( + rvfi_csr_mseccfgh_rdata == '0 + ) else `uvm_error(info_tag, "mseccfgh not zero"); + + // Translate write-attempts to legal values function automatic pmpncfg_t rectify_cfg_write (pmpncfg_t cfg_pre, pmpncfg_t cfg_attempt); diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_rvfi_assert.sv b/cv32e40s/tb/assertions/uvmt_cv32e40s_rvfi_assert.sv similarity index 97% rename from cv32e40s/tb/uvmt/uvmt_cv32e40s_rvfi_assert.sv rename to cv32e40s/tb/assertions/uvmt_cv32e40s_rvfi_assert.sv index 4cc7f84419..36414897a8 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_rvfi_assert.sv +++ b/cv32e40s/tb/assertions/uvmt_cv32e40s_rvfi_assert.sv @@ -348,8 +348,8 @@ module uvmt_cv32e40s_rvfi_assert ) else `uvm_error(info_tag, "!store->!exce, exce->store"); + // Disassembler -// Disassembler a_unknowninstr_trap: assert property ( (rvfi_if.instr_asm.instr == UNKNOWN_INSTR) && rvfi_if.rvfi_valid |-> @@ -357,6 +357,14 @@ module uvmt_cv32e40s_rvfi_assert ) else `uvm_error(info_tag, "Unknown instruction is not trapped"); + // Exception's don't update GPRs + + a_exceptions_dont_update_gprs: assert property ( + rvfi_valid && rvfi_trap.exception + |-> + (rvfi_if.rvfi_rd1_addr == 0) + ) else `uvm_error(info_tag, "exceptions shouldn't update gprs"); + endmodule : uvmt_cv32e40s_rvfi_assert diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_rvfi_cov.sv b/cv32e40s/tb/assertions/uvmt_cv32e40s_rvfi_cov.sv similarity index 100% rename from cv32e40s/tb/uvmt/uvmt_cv32e40s_rvfi_cov.sv rename to cv32e40s/tb/assertions/uvmt_cv32e40s_rvfi_cov.sv diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_umode_assert.sv b/cv32e40s/tb/assertions/uvmt_cv32e40s_umode_assert.sv similarity index 98% rename from cv32e40s/tb/uvmt/uvmt_cv32e40s_umode_assert.sv rename to cv32e40s/tb/assertions/uvmt_cv32e40s_umode_assert.sv index fa86e34698..67dd3cff70 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_umode_assert.sv +++ b/cv32e40s/tb/assertions/uvmt_cv32e40s_umode_assert.sv @@ -932,21 +932,21 @@ module uvmt_cv32e40s_umode_assert // vplan:InstrProt - a_instr_prot: assert property ( + a_rvfi_instr_prot: assert property ( rvfi_valid |-> - (rvfi_if.instr_prot[2:1] == rvfi_if.rvfi_mode) || + (rvfi_if.rvfi_instr_prot[2:1] == rvfi_if.rvfi_mode) || (rvfi_if.rvfi_trap.exception_cause == cv32e40s_pkg::EXC_CAUSE_INSTR_FAULT) || (rvfi_trap.debug_cause == DBG_CAUSE_TRIGGER) //Note: Triggers can overshadow access faults ) else `uvm_error(info_tag, "the prot on fetch must match the mode on retirement"); - a_instr_prot_legal: assert property ( + a_rvfi_instr_prot_legal: assert property ( rvfi_valid && (rvfi_if.rvfi_trap.exception_cause != cv32e40s_pkg::EXC_CAUSE_INSTR_FAULT) |-> - (rvfi_if.instr_prot[2:0] inside {3'b 000, 3'b 110}) - ) else `uvm_error(info_tag, "instr_prot illegal value"); + (rvfi_if.rvfi_instr_prot[2:0] inside {3'b 000, 3'b 110}) + ) else `uvm_error(info_tag, "rvfi_instr_prot illegal value"); a_prot_iside_legal: assert property ( obi_iside_prot inside {3'b 000, 3'b 110} @@ -959,14 +959,14 @@ module uvmt_cv32e40s_umode_assert rvfi_valid && (rvfi_if.rvfi_mem_rmask || rvfi_if.rvfi_mem_wmask) |-> - (rvfi_if.mem_prot[2:1] == effective_rvfi_privmode) + (rvfi_if.rvfi_mem_prot[2:1] == effective_rvfi_privmode) ) else `uvm_error(info_tag, "the prot on load/store must match the effective mode on retirement"); a_data_prot_legal: assert property ( rvfi_valid && (rvfi_if.rvfi_trap.exception_cause != cv32e40s_pkg::EXC_CAUSE_INSTR_FAULT) |-> - (rvfi_if.mem_prot[2:0] inside {3'b 001, 3'b 111}) + (rvfi_if.rvfi_mem_prot[2:0] inside {3'b 001, 3'b 111}) ) else `uvm_error(info_tag, "data_prot illegal value"); a_prot_dside_legal: assert property ( @@ -977,7 +977,7 @@ module uvmt_cv32e40s_umode_assert logic [NMEM-1:0] mem_act; for (genvar i = 0; i < NMEM; i++) begin: gen_data_prot_equals always_comb begin - data_prot_equals[i] = (rvfi_if.mem_prot[i*3+:3] == rvfi_if.mem_prot[2:0]); + data_prot_equals[i] = (rvfi_if.rvfi_mem_prot[i*3+:3] == rvfi_if.rvfi_mem_prot[2:0]); mem_act[i] = |rvfi_if.check_mem_act(i); end end @@ -1008,7 +1008,7 @@ module uvmt_cv32e40s_umode_assert rvfi_if.rvfi_valid && rvfi_if.rvfi_dbg_mode |-> - (rvfi_if.instr_prot[2:1] == MODE_M) || + (rvfi_if.rvfi_instr_prot[2:1] == MODE_M) || (rvfi_if.rvfi_trap.exception_cause == cv32e40s_pkg::EXC_CAUSE_INSTR_FAULT) ) else `uvm_error(info_tag, "dmode should fetch as mmode"); @@ -1017,7 +1017,7 @@ module uvmt_cv32e40s_umode_assert rvfi_valid && (|rvfi_if.rvfi_mem_rmask || |rvfi_if.rvfi_mem_wmask) |-> - (rvfi_if.mem_prot[2:1] == effective_rvfi_privmode) + (rvfi_if.rvfi_mem_prot[2:1] == effective_rvfi_privmode) ) else `uvm_error(info_tag, "dmode should fetch as effective mode"); diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_umode_cov.sv b/cv32e40s/tb/assertions/uvmt_cv32e40s_umode_cov.sv similarity index 100% rename from cv32e40s/tb/uvmt/uvmt_cv32e40s_umode_cov.sv rename to cv32e40s/tb/assertions/uvmt_cv32e40s_umode_cov.sv diff --git a/cv32e40s/tb/uvmt/support_logic/uvmt_cv32e40s_rchk_shim.sv b/cv32e40s/tb/uvmt/support_logic/uvmt_cv32e40s_rchk_shim.sv new file mode 100644 index 0000000000..2b5cfe79d0 --- /dev/null +++ b/cv32e40s/tb/uvmt/support_logic/uvmt_cv32e40s_rchk_shim.sv @@ -0,0 +1,198 @@ +// Copyright 2023 Silicon Labs, Inc. +// +// This file, and derivatives thereof are licensed under the +// Solderpad License, Version 2.0 (the "License"). +// +// Use of this file means you agree to the terms and conditions +// of the license and are in full compliance with the License. +// +// You may obtain a copy of the License at: +// +// https://solderpad.org/licenses/SHL-2.0/ +// +// Unless required by applicable law or agreed to in writing, software +// and hardware implementations thereof distributed under the License +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, EITHER EXPRESSED OR IMPLIED. +// +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////// +// Engineer: Oystein Knauserud - oystein.knauserud@silabs.com // +// // +// Design Name: cv32e40s_rchk_shim // +// Project Name: CV32E40S // +// Language: SystemVerilog // +// // +// Description: Module keeps track of which OBI response should carry a // +// legal rchk value and which do not. Scrambles rchk for // +// non-integrity regions as defined by PMA_CFG. // +//////////////////////////////////////////////////////////////////////////////// + +module uvmt_cv32e40s_rchk_shim import cv32e40s_pkg::*; +#( parameter int unsigned MAX_OUTSTANDING = 2, + parameter int PMA_NUM_REGIONS = 0, + parameter pma_cfg_t PMA_CFG[PMA_NUM_REGIONS-1:0] = '{default:PMA_R_DEFAULT}, + parameter logic [31:0] DM_REGION_START = 32'hF0000000, + parameter logic [31:0] DM_REGION_END = 32'hF0003FFF, + parameter logic GENERATE_VALID_RCHK = 0 + ) +( + input logic clk, + input logic rst_n, + + // OBI address phase handshake + input logic req_i, + input logic gnt_i, + input logic dbg_i, + input logic [31:0] addr_i, + + // OBI response phase signals + input logic [31:0] rdata_i, + input logic rvalid_i, + input logic err_i, + input logic [4:0] rchk_i, // From outside + + // rchk output + output logic [4:0] rchk_o // to cv32e40s + +); + + localparam OUTSTND_CNT_WIDTH = $clog2(MAX_OUTSTANDING+1); + + + // FIFO is 1 bit deeper than the maximum value of bus_cnt_i + // Index 0 is tied low to enable direct use of bus_cnt_i to pick correct FIFO index. + logic [MAX_OUTSTANDING:0] fifo_q; + logic req_has_integrity; + logic resp_has_integrity; + + // Outstanding counter signals + logic [OUTSTND_CNT_WIDTH-1:0] cnt_q; // Transaction counter + logic [OUTSTND_CNT_WIDTH-1:0] next_cnt; // Next value for cnt_q + logic count_up; + logic count_down; + + // PMA lookup + pma_cfg_t pma_cfg; + logic [31:0] word_addr; + + // Check for access to DM_REGION in debug mode + logic dm_access_debug; + + assign dm_access_debug = (addr_i >= DM_REGION_START) && (addr_i <= DM_REGION_END) && dbg_i; + + ///////////////////////////////////////////////////////////// + // Outstanding transactions counter + // Used for tracking the integrity attribute + ///////////////////////////////////////////////////////////// + assign count_up = req_i && gnt_i; // Increment upon accepted transfer request + assign count_down = rvalid_i; // Decrement upon accepted transfer response + + always_comb begin + case ({count_up, count_down}) + 2'b00 : begin + next_cnt = cnt_q; + end + 2'b01 : begin + next_cnt = cnt_q - 1'b1; + end + 2'b10 : begin + next_cnt = cnt_q + 1'b1; + end + 2'b11 : begin + next_cnt = cnt_q; + end + default:; + endcase + end + + always_ff @(posedge clk, negedge rst_n) + begin + if (rst_n == 1'b0) begin + cnt_q <= '0; + end else begin + cnt_q <= next_cnt; + end + end + + ////////////////////// + // Integrity tracking + ////////////////////// + + // PMA addresses are word addresses + assign word_addr = {2'b00, addr_i[31:2]}; + + generate + if(PMA_NUM_REGIONS == 0) begin: no_pma + + always_comb begin + // PMA is deconfigured, use NO_PMA_R_DEFAULT as default. + pma_cfg = NO_PMA_R_DEFAULT; + + // Access to debug module in debug mode has no integrity + req_has_integrity = dm_access_debug ? 1'b0 : pma_cfg.integrity; + end + + end + else begin: pma + + // Identify PMA region + always_comb begin + + // If no match, use default PMA config as default. + pma_cfg = PMA_R_DEFAULT; + + for(int i = PMA_NUM_REGIONS-1; i >= 0; i--) begin + if((word_addr >= PMA_CFG[i].word_addr_low) && + (word_addr < PMA_CFG[i].word_addr_high)) begin + pma_cfg = PMA_CFG[i]; + end + end + + // Access to debug module in debug mode has no integrity + req_has_integrity = dm_access_debug ? 1'b0 : pma_cfg.integrity; + end + end + + endgenerate + + // FIFO to keep track of which responses come from an integrity enabled region + always_ff @ (posedge clk, negedge rst_n) begin + if (!rst_n) begin + fifo_q <= '0; + end + else begin + if (req_i && gnt_i) begin + // Accepted address phase, populate FIFO with expected integrity + fifo_q <= {fifo_q[MAX_OUTSTANDING-1:1], req_has_integrity, 1'b0}; + end + end + end + + assign resp_has_integrity = fifo_q[cnt_q]; + + // Invert all rchk bits if response is from a non-integrity region, else + // generate correct response + always_comb begin + if (GENERATE_VALID_RCHK == 1) begin + rchk_o = resp_has_integrity ? { + ^{err_i, 1'b0}, + ^{rdata_i[31:24]}, + ^{rdata_i[23:16]}, + ^{rdata_i[15:8]}, + ^{rdata_i[7:0]} + } : ~{ + ^{err_i, 1'b0}, + ^{rdata_i[31:24]}, + ^{rdata_i[23:16]}, + ^{rdata_i[15:8]}, + ^{rdata_i[7:0]} + }; + end else begin + rchk_o = resp_has_integrity ? rchk_i : ~rchk_i; + end + end + +endmodule : uvmt_cv32e40s_rchk_shim diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_clic_interrupt_assert.sv b/cv32e40s/tb/uvmt/uvmt_cv32e40s_clic_interrupt_assert.sv index 0645e77a23..348fe5807a 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_clic_interrupt_assert.sv +++ b/cv32e40s/tb/uvmt/uvmt_cv32e40s_clic_interrupt_assert.sv @@ -780,6 +780,13 @@ module uvmt_cv32e40s_clic_interrupt_assert end end + covergroup cg_clic @(posedge clk_i); + option.per_instance = 1; + cp_lvl: coverpoint irq_level{ bins values[] = {[0:255]};} + endgroup + + cg_clic clic_cg = new; + assign core_not_in_debug = debug_running; assign core_in_debug = !core_not_in_debug; @@ -1187,39 +1194,25 @@ module uvmt_cv32e40s_clic_interrupt_assert effective_clic_level = mintthresh_fields.th > mintstatus_fields.mil ? mintthresh_fields.th : mintstatus_fields.mil; end - sequence seq_irq_pend(bit ok = 1'b1); + sequence seq_irq_pend_ok(); @(posedge clk_i) // valid pending - ok ##0 ( - (mstatus_fields.mie - && $past(clic.irq) - && $past(clic.priv) == current_priv_mode - && $past(clic.level) > effective_clic_level) - or - ($past(clic.irq) - && $past(clic.priv) > current_priv_mode - && $past(clic.level) > 0) - ) - or - // no valid pending - !ok ##0 ( - !(mstatus_fields.mie - && $past(clic.irq) - && $past(clic.priv) == current_priv_mode - && $past(clic.level) > effective_clic_level) - and - !($past(clic.irq) - && $past(clic.priv) > current_priv_mode - && $past(clic.level) > 0) - ) + (mstatus_fields.mie + && $past(clic.irq) + && $past(clic.priv) == current_priv_mode + && $past(clic.level) > effective_clic_level) + or + ($past(clic.irq) + && $past(clic.priv) > current_priv_mode + && $past(clic.level) > 0) ; - endsequence : seq_irq_pend + endsequence : seq_irq_pend_ok property p_irq_ack_valid; irq_ack |-> - seq_irq_pend(1'b1) + seq_irq_pend_ok ; endproperty : p_irq_ack_valid @@ -1231,9 +1224,24 @@ module uvmt_cv32e40s_clic_interrupt_assert // ------------------------------------------------------------------------ // There should be no irq_ack unless there was a pending and enabled irq // ------------------------------------------------------------------------ + + sequence seq_irq_pend_notok(); + @(posedge clk_i) + + // no valid pending + !(mstatus_fields.mie + && $past(clic.irq) + && $past(clic.priv) == current_priv_mode + && $past(clic.level) > effective_clic_level) + and + !($past(clic.irq) + && $past(clic.priv) > current_priv_mode + && $past(clic.level) > 0) + ; + endsequence : seq_irq_pend_notok property p_no_irq_no_ack; // Never irq_ack unless we had a valid and pending interrupt present. - seq_irq_pend(1'b0).triggered + seq_irq_pend_notok.triggered |-> !irq_ack ; @@ -1872,16 +1880,18 @@ module uvmt_cv32e40s_clic_interrupt_assert // ------------------------------------------------------------------------ property p_mtvt_alignment_correct; - disable iff (!rst_ni || N_MTVT <= 6) // Disable if field does not exist + disable iff (!rst_ni) mtvt_fields.base_n_0 == '0; endproperty : p_mtvt_alignment_correct - a_mtvt_alignment_correct: assert property (p_mtvt_alignment_correct) - else - `uvm_error(info_tag, - $sformatf("mtvt alignment should have been %d bytes, mtvt: %08x", - (2 ** N_MTVT), - mtvt)); + if (N_MTVT > 6) begin: gen_mtvt_alignment_correct // Disable if field does not exist + a_mtvt_alignment_correct: assert property (p_mtvt_alignment_correct) + else + `uvm_error(info_tag, + $sformatf("mtvt alignment should have been %d bytes, mtvt: %08x", + (2 ** N_MTVT), + mtvt)); + end // ------------------------------------------------------------------------ // mepc is always set correctly when taking an interrupt diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv b/cv32e40s/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv index 9ebae7e2e5..90c1523d5c 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv +++ b/cv32e40s/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv @@ -44,9 +44,9 @@ module uvmt_cv32e40s_dut_wrap #( - parameter INSTR_ADDR_WIDTH = 32, - parameter INSTR_RDATA_WIDTH = 32, - parameter RAM_ADDR_WIDTH = 20 + parameter INSTR_ADDR_WIDTH = 32, + parameter INSTR_RDATA_WIDTH = 32, + parameter RAM_ADDR_WIDTH = 20 ) ( uvma_clknrst_if_t clknrst_if, @@ -55,7 +55,6 @@ module uvmt_cv32e40s_dut_wrap uvma_wfe_wu_if_t wfe_wu_if, uvmt_cv32e40s_vp_status_if_t vp_status_if, uvme_cv32e40s_core_cntrl_if_t core_cntrl_if, - uvmt_cv32e40s_core_status_if_t core_status_if, uvma_obi_memory_if_t obi_instr_if, uvma_obi_memory_if_t obi_data_if, uvma_fencei_if_t fencei_if @@ -67,8 +66,11 @@ module uvmt_cv32e40s_dut_wrap logic debug_pc_valid; logic [31:0] debug_pc; - logic alert_major; - logic alert_minor; + logic alert_major; + logic alert_minor; + + logic [4:0] instr_rchk_shim; + logic [4:0] data_rchk_shim; // instantiate the core @@ -115,7 +117,7 @@ module uvmt_cv32e40s_dut_wrap .instr_dbg_o ( obi_instr_if.dbg ), .instr_memtype_o ( obi_instr_if.memtype ), .instr_rdata_i ( obi_instr_if.rdata ), - .instr_rchk_i ( obi_instr_if.rchk ), + .instr_rchk_i ( instr_rchk_shim ), .instr_rvalid_i ( obi_instr_if.rvalid ), .instr_rvalidpar_i ( obi_instr_if.rvalidpar ), .instr_err_i ( obi_instr_if.err ), @@ -135,7 +137,7 @@ module uvmt_cv32e40s_dut_wrap .data_dbg_o ( obi_data_if.dbg ), .data_memtype_o ( obi_data_if.memtype ), .data_rdata_i ( obi_data_if.rdata ), - .data_rchk_i ( obi_data_if.rchk ), + .data_rchk_i ( data_rchk_shim ), .data_err_i ( obi_data_if.err ), .mcycle_o ( /*todo: connect */ ), @@ -163,7 +165,54 @@ module uvmt_cv32e40s_dut_wrap .alert_minor_o ( alert_minor ), .fetch_enable_i ( core_cntrl_if.fetch_en ), - .core_sleep_o ( core_status_if.core_busy ) + .core_sleep_o () + ); + + // instantiate rchk shim + uvmt_cv32e40s_rchk_shim#( + .MAX_OUTSTANDING (2), + .PMA_NUM_REGIONS (uvmt_cv32e40s_base_test_pkg::CORE_PARAM_PMA_NUM_REGIONS), + .PMA_CFG (uvmt_cv32e40s_base_test_pkg::CORE_PARAM_PMA_CFG), + .GENERATE_VALID_RCHK (0) + ) cv32e40s_rchk_shim_instr_i( + .clk ( clknrst_if.clk ), + .rst_n ( clknrst_if.reset_n ), + + // OBI address phase handshake + .req_i ( obi_instr_if.req ), + .gnt_i ( obi_instr_if.gnt ), + .dbg_i ( obi_instr_if.dbg ), + .addr_i ( obi_instr_if.addr ), + + // OBI response phase signals + .rdata_i ( obi_instr_if.rdata ), + .rvalid_i ( obi_instr_if.rvalid ), + .err_i ( obi_instr_if.err ), + .rchk_i ( obi_instr_if.rchk ), + .rchk_o ( instr_rchk_shim ) + ); + + uvmt_cv32e40s_rchk_shim#( + .MAX_OUTSTANDING (2), + .PMA_NUM_REGIONS (uvmt_cv32e40s_base_test_pkg::CORE_PARAM_PMA_NUM_REGIONS), + .PMA_CFG (uvmt_cv32e40s_base_test_pkg::CORE_PARAM_PMA_CFG), + .GENERATE_VALID_RCHK (0) + ) cv32e40s_rchk_shim_data_i( + .clk ( clknrst_if.clk ), + .rst_n ( clknrst_if.reset_n ), + + // OBI address phase handshake + .req_i ( obi_data_if.req ), + .gnt_i ( obi_data_if.gnt ), + .dbg_i ( obi_data_if.dbg ), + .addr_i ( obi_data_if.addr ), + + // OBI response phase signals + .rdata_i ( obi_data_if.rdata ), + .rvalid_i ( obi_data_if.rvalid ), + .err_i ( obi_data_if.err ), + .rchk_i ( obi_data_if.rchk ), + .rchk_o ( data_rchk_shim ) ); endmodule : uvmt_cv32e40s_dut_wrap diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_tb.sv b/cv32e40s/tb/uvmt/uvmt_cv32e40s_tb.sv index 30ff8a953d..70efa042b2 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_tb.sv +++ b/cv32e40s/tb/uvmt/uvmt_cv32e40s_tb.sv @@ -82,8 +82,6 @@ module uvmt_cv32e40s_tb; .exit_valid(), .exit_value()); // Status information generated by the Virtual Peripherals in the DUT WRAPPER memory. uvme_cv32e40s_core_cntrl_if_t core_cntrl_if(); - uvmt_cv32e40s_core_status_if_t core_status_if(.core_busy(), - .sec_lvl()); // Core status outputs // RVVI SystemVerilog Interface `ifndef FORMAL @@ -103,7 +101,6 @@ module uvmt_cv32e40s_tb; .interrupt_if (interrupt_if), .vp_status_if (vp_status_if), .core_cntrl_if (core_cntrl_if), - .core_status_if (core_status_if), .obi_instr_if (obi_instr_if), .obi_data_if (obi_data_if), .fencei_if (fencei_if), @@ -164,45 +161,55 @@ module uvmt_cv32e40s_tb; // "rvfi_instr_if" bind cv32e40s_wrapper - uvma_rvfi_instr_if_t#(uvmt_cv32e40s_base_test_pkg::ILEN, - uvmt_cv32e40s_base_test_pkg::XLEN) rvfi_instr_if(.clk(clk_i), - .reset_n(rst_ni), - - .rvfi_valid(rvfi_i.rvfi_valid[0]), - .rvfi_order(rvfi_i.rvfi_order[uvma_rvfi_pkg::ORDER_WL*0+:uvma_rvfi_pkg::ORDER_WL]), - .rvfi_insn(rvfi_i.rvfi_insn[uvmt_cv32e40s_base_test_pkg::ILEN*0+:uvmt_cv32e40s_base_test_pkg::ILEN]), - .rvfi_trap(rvfi_i.rvfi_trap), - .rvfi_halt(rvfi_i.rvfi_halt[0]), - .rvfi_intr(rvfi_i.rvfi_intr), - .rvfi_dbg(rvfi_i.rvfi_dbg), - .rvfi_dbg_mode(rvfi_i.rvfi_dbg_mode), - .rvfi_nmip(rvfi_i.rvfi_nmip), - .rvfi_mode(rvfi_i.rvfi_mode[uvma_rvfi_pkg::MODE_WL*0+:uvma_rvfi_pkg::MODE_WL]), - .rvfi_ixl(rvfi_i.rvfi_ixl[uvma_rvfi_pkg::IXL_WL*0+:uvma_rvfi_pkg::IXL_WL]), - .rvfi_pc_rdata(rvfi_i.rvfi_pc_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_pc_wdata(rvfi_i.rvfi_pc_wdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_rs1_addr(rvfi_i.rvfi_rs1_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), - .rvfi_rs1_rdata(rvfi_i.rvfi_rs1_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_rs2_addr(rvfi_i.rvfi_rs2_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), - .rvfi_rs2_rdata(rvfi_i.rvfi_rs2_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_rs3_addr('0), - .rvfi_rs3_rdata('0), - .rvfi_rd1_addr(rvfi_i.rvfi_rd_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), - .rvfi_rd1_wdata(rvfi_i.rvfi_rd_wdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_rd2_addr('0), - .rvfi_rd2_wdata('0), - .rvfi_gpr_rdata(rvfi_i.rvfi_gpr_rdata[32*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:32*uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_gpr_rmask(rvfi_i.rvfi_gpr_rmask[32*0 +:32]), - .rvfi_gpr_wdata(rvfi_i.rvfi_gpr_wdata[32*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:32*uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_gpr_wmask(rvfi_i.rvfi_gpr_wmask[32*0 +:32]), - .rvfi_mem_addr(rvfi_i.rvfi_mem_addr[ uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_mem_rdata(rvfi_i.rvfi_mem_rdata[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_mem_rmask(rvfi_i.rvfi_mem_rmask[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8]), - .rvfi_mem_wdata(rvfi_i.rvfi_mem_wdata[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_mem_wmask(rvfi_i.rvfi_mem_wmask[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8]), - .instr_prot(rvfi_i.rvfi_instr_prot), - .mem_prot(rvfi_i.rvfi_mem_prot) - ); + uvma_rvfi_instr_if_t#( + uvmt_cv32e40s_base_test_pkg::ILEN, + uvmt_cv32e40s_base_test_pkg::XLEN + ) rvfi_instr_if( + .clk (clk_i), + .reset_n (rst_ni), + + .rvfi_valid (rvfi_i.rvfi_valid[0]), + .rvfi_order (rvfi_i.rvfi_order[uvma_rvfi_pkg::ORDER_WL*0+:uvma_rvfi_pkg::ORDER_WL]), + .rvfi_insn (rvfi_i.rvfi_insn[uvmt_cv32e40s_base_test_pkg::ILEN*0+:uvmt_cv32e40s_base_test_pkg::ILEN]), + .rvfi_trap (rvfi_i.rvfi_trap), + .rvfi_halt (rvfi_i.rvfi_halt[0]), + .rvfi_intr (rvfi_i.rvfi_intr), + .rvfi_dbg (rvfi_i.rvfi_dbg), + .rvfi_dbg_mode (rvfi_i.rvfi_dbg_mode), + .rvfi_nmip (rvfi_i.rvfi_nmip), + .rvfi_mode (rvfi_i.rvfi_mode[uvma_rvfi_pkg::MODE_WL*0+:uvma_rvfi_pkg::MODE_WL]), + .rvfi_ixl (rvfi_i.rvfi_ixl[uvma_rvfi_pkg::IXL_WL*0+:uvma_rvfi_pkg::IXL_WL]), + .rvfi_pc_rdata (rvfi_i.rvfi_pc_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_pc_wdata (rvfi_i.rvfi_pc_wdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_rs1_addr (rvfi_i.rvfi_rs1_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), + .rvfi_rs1_rdata (rvfi_i.rvfi_rs1_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_rs2_addr (rvfi_i.rvfi_rs2_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), + .rvfi_rs2_rdata (rvfi_i.rvfi_rs2_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_rs3_addr ('0), + .rvfi_rs3_rdata ('0), + .rvfi_rd1_addr (rvfi_i.rvfi_rd_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), + .rvfi_rd1_wdata (rvfi_i.rvfi_rd_wdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_rd2_addr ('0), + .rvfi_rd2_wdata ('0), + .rvfi_gpr_rdata (rvfi_i.rvfi_gpr_rdata[32*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:32*uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_gpr_rmask (rvfi_i.rvfi_gpr_rmask[32*0 +:32]), + .rvfi_gpr_wdata (rvfi_i.rvfi_gpr_wdata[32*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:32*uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_gpr_wmask (rvfi_i.rvfi_gpr_wmask[32*0 +:32]), + .rvfi_mem_addr (rvfi_i.rvfi_mem_addr[ uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_mem_rdata (rvfi_i.rvfi_mem_rdata[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_mem_rmask (rvfi_i.rvfi_mem_rmask[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8]), + .rvfi_mem_wdata (rvfi_i.rvfi_mem_wdata[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_mem_wmask (rvfi_i.rvfi_mem_wmask[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8]), + .rvfi_instr_prot (rvfi_i.rvfi_instr_prot), + .rvfi_instr_memtype (rvfi_i.rvfi_instr_memtype), + .rvfi_instr_dbg (rvfi_i.rvfi_instr_dbg), + .rvfi_mem_prot (rvfi_i.rvfi_mem_prot), + .rvfi_mem_exokay (rvfi_i.rvfi_mem_exokay), + .rvfi_mem_err (rvfi_i.rvfi_mem_err), + .rvfi_mem_atop (rvfi_i.rvfi_mem_atop), + .rvfi_mem_memtype (rvfi_i.rvfi_mem_memtype), + .rvfi_mem_dbg (rvfi_i.rvfi_mem_dbg) + ); // RVFI CSR binds `RVFI_CSR_BIND(cpuctrl) @@ -1484,9 +1491,8 @@ module uvmt_cv32e40s_tb; uvmt_cv32e40s_support_logic_module_o_if_t support_logic_module_o_if(); `ifndef COREV_ASSERT_OFF - bind cv32e40s_pmp : - uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i - uvmt_cv32e40s_pmp_assert #( + bind uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pmp.pmp_i + uvmt_cv32e40s_pmp_assert#( .PMP_GRANULARITY (PMP_GRANULARITY), .PMP_NUM_REGIONS (PMP_NUM_REGIONS), .IS_INSTR_SIDE (1'b1), @@ -1503,8 +1509,7 @@ module uvmt_cv32e40s_tb; `endif `ifndef COREV_ASSERT_OFF - bind cv32e40s_pmp : - uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i + bind uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.load_store_unit_i.mpu_i.pmp.pmp_i uvmt_cv32e40s_pmp_assert#( .PMP_GRANULARITY (PMP_GRANULARITY), .PMP_NUM_REGIONS (PMP_NUM_REGIONS), @@ -1528,6 +1533,7 @@ module uvmt_cv32e40s_tb; .PMP_NUM_REGIONS (uvmt_cv32e40s_base_test_pkg::CORE_PARAM_PMP_NUM_REGIONS) ) pmprvfi_assert_i ( .rvfi_if (dut_wrap.cv32e40s_wrapper_i.rvfi_instr_if), + .support_if (support_logic_module_o_if.slave_mp), .rvfi_mem_addr (rvfi_mem_addr [31:0]), .rvfi_mem_wmask (rvfi_mem_wmask[ 3:0]), .rvfi_mem_rmask (rvfi_mem_rmask[ 3:0]), @@ -2047,7 +2053,6 @@ module uvmt_cv32e40s_tb; // Virtual Peripheral Status interface uvm_config_db#(virtual uvmt_cv32e40s_vp_status_if_t )::set(.cntxt(null), .inst_name("*"), .field_name("vp_status_vif"), .value(vp_status_if) ); uvm_config_db#(virtual uvme_cv32e40s_core_cntrl_if_t )::set(.cntxt(null), .inst_name("*"), .field_name("core_cntrl_vif"), .value(core_cntrl_if) ); - uvm_config_db#(virtual uvmt_cv32e40s_core_status_if_t )::set(.cntxt(null), .inst_name("*"), .field_name("core_status_vif"), .value(core_status_if) ); uvm_config_db#(virtual uvmt_cv32e40s_debug_cov_assert_if_t )::set(.cntxt(null), .inst_name("*.env"), .field_name("debug_cov_vif"),.value(dut_wrap.cv32e40s_wrapper_i.debug_cov_assert_if)); uvm_config_db#(virtual uvmt_cv32e40s_support_logic_module_o_if_t )::set(.cntxt(null), .inst_name("*.env"), .field_name("support_logic_vif"),.value(dut_wrap.cv32e40s_wrapper_i.support_logic_module_o_if)); diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_tb_files.flist b/cv32e40s/tb/uvmt/uvmt_cv32e40s_tb_files.flist index d913d0e03c..a092c6618f 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_tb_files.flist +++ b/cv32e40s/tb/uvmt/uvmt_cv32e40s_tb_files.flist @@ -18,38 +18,39 @@ ${DV_UVMT_PATH}/uvmt_cv32e40s_dut_wrap.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_tb.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_fencei_assert.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_pmp_assert.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_pmprvfi_assert.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_rvfi_assert.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_umode_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_clic_interrupt_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_debug_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_triggers_assert_cov.sv -${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_fencei_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_integration_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_interrupt_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_pma_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_pmp_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_pmprvfi_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_rvfi_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_umode_assert.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_triggers_assert_cov.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_bus_protocol_hardening_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_data_independent_timing_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_pc_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_reduced_profiling_infrastructure_assert.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_dummy_and_hint_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_csrs_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_csrs_clic_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_csrs_interrupt_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_csrs_pmp_assert.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_pc_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_interface_integrity_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_dummy_and_hint_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_bus_protocol_hardening_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_security_alerts_assert.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_reduced_profiling_infrastructure_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_register_file_ecc_assert.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_security_alerts_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_zc_assert.sv ${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_pma_model.sv ${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_pmp_model.sv -${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_obi_phases_monitor.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_rvfi_cov.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_umode_cov.sv +${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_rchk_shim.sv ${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_fifo.sv -${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_trigger_match_mem.sv +${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_obi_phases_monitor.sv ${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_trigger_match.sv +${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_trigger_match_mem.sv ${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_support_logic.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_pma_cov.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_rvfi_cov.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_umode_cov.sv diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_interface_integrity_assert.sv b/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_interface_integrity_assert.sv index 68480736fa..54b685ea37 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_interface_integrity_assert.sv +++ b/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_interface_integrity_assert.sv @@ -261,7 +261,7 @@ module uvmt_cv32e40s_xsecure_interface_integrity_assert //Verify that the received and generated checksums are correct property p_checksum(req, chk_input, chk_calculated); - if_valid //TODO: do we need this one? + if_valid && req |-> chk_input == chk_calculated; @@ -285,6 +285,7 @@ module uvmt_cv32e40s_xsecure_interface_integrity_assert a_xsecure_integrity_instr_rchk: assert property ( obi_instr_rvalid + && support_if.instr_req_had_integrity |-> obi_instr_resp_packet.rchk == rchk_instr_calculated ); @@ -292,6 +293,7 @@ module uvmt_cv32e40s_xsecure_interface_integrity_assert property p_checksum_data_rchk(memory_op, rvalid, chk_input, chk_calculated); memory_op && rvalid + && support_if.data_req_had_integrity |-> chk_input == chk_calculated; endproperty diff --git a/cv32e40s/tests/cfg/pma_test_cfg_2.yaml b/cv32e40s/tests/cfg/pma_test_cfg_2.yaml index 0edf69a0db..185269bf16 100644 --- a/cv32e40s/tests/cfg/pma_test_cfg_2.yaml +++ b/cv32e40s/tests/cfg/pma_test_cfg_2.yaml @@ -2,6 +2,7 @@ name: pma_test_cfg_2 description: PMA configuration for the PMA_TEST_CFG_2 test case compile_flags: > +define+PMA_TEST_CFG_2 + +define+CLIC_EN +define+ZBA_ZBB_ZBC_ZBS plusargs: > +enable_pma=1 diff --git a/cv32e40s/tests/programs/corev-dv/corev_rand_data_obi_err_debug/test.yaml b/cv32e40s/tests/programs/corev-dv/corev_rand_data_obi_err_debug/test.yaml index 467563d1ea..ff832c3fea 100644 --- a/cv32e40s/tests/programs/corev-dv/corev_rand_data_obi_err_debug/test.yaml +++ b/cv32e40s/tests/programs/corev-dv/corev_rand_data_obi_err_debug/test.yaml @@ -5,6 +5,7 @@ description: > plusargs: > +random_fetch_toggle +obi_memory_data_random_err_enabled + +obi_memory_data_random_err_await_goahead +obi_memory_data_one_shot_err_enabled +gen_irq_noise +gen_random_debug diff --git a/cv32e40s/tests/programs/custom/clic/clic.c b/cv32e40s/tests/programs/custom/clic/clic.c index e8e4d27b3d..2a8e908972 100644 --- a/cv32e40s/tests/programs/custom/clic/clic.c +++ b/cv32e40s/tests/programs/custom/clic/clic.c @@ -35,7 +35,7 @@ // MUST be 31 or less (bit position-1 in result array determines test pass/fail // status, thus we are limited to 31 tests with this construct. -#define NUM_TESTS 23 +#define NUM_TESTS 24 // Set which test index to start testing at (for quickly running specific tests during development) #define START_TEST_IDX 0 // Abort test at first self-check fail, useful for debugging. @@ -205,7 +205,11 @@ const uint32_t MCAUSE_MPIE_MASK = 0x1 << MCAUSE_MPIE_OFFSET; volatile verbosity_t global_verbosity = V_LOW; extern volatile uint32_t mtvt_table; +extern volatile uint32_t mtvt_table_mret; +extern volatile uint32_t mtvt_table_mret_dest; extern volatile uint32_t recovery_pt; +extern volatile uint32_t recovery_pt_mret; +extern volatile uint32_t recovery_pt_mret_ptr; volatile uint32_t test_fail_asm; @@ -232,6 +236,7 @@ uint32_t w_mip_notrap_r_zero(uint32_t index, uint8_t report_name); uint32_t w_mtvt_rd_alignment(uint32_t index, uint8_t report_name); uint32_t w_mtvec_rd_alignment(uint32_t index, uint8_t report_name); uint32_t invalid_mtvt_ptr_exec(uint32_t index, uint8_t report_name); +uint32_t invalid_mtvt_ptr_exec_mret(uint32_t index, uint8_t report_name); uint32_t r_mnxti_without_irq(uint32_t index, uint8_t report_name); uint32_t rw_mnxti_without_irq_illegal(uint32_t index, uint8_t report_name); uint32_t r_mnxti_with_pending_irq(uint32_t index, uint8_t report_name); @@ -384,19 +389,20 @@ int main(int argc, char **argv){ tests[7] = w_mtvt_rd_alignment; tests[8] = w_mtvec_rd_alignment; tests[9] = invalid_mtvt_ptr_exec; - tests[10] = r_mnxti_without_irq; - tests[11] = rw_mnxti_without_irq_illegal; - tests[12] = r_mnxti_with_pending_irq; - tests[13] = r_mnxti_with_lower_lvl_pending_irq; - tests[14] = w_mnxti_side_effects; - tests[15] = rw_mscratchcsw; - tests[16] = rw_mscratchcsw_illegal; - tests[17] = rw_mscratchcswl; - tests[18] = rw_mscratchcswl_illegal; - tests[19] = mret_with_minhv; - tests[20] = mintthresh_lower; - tests[21] = mintthresh_higher; - tests[22] = mintthresh_equal; + tests[10] = invalid_mtvt_ptr_exec_mret; + tests[11] = r_mnxti_without_irq; + tests[12] = rw_mnxti_without_irq_illegal; + tests[13] = r_mnxti_with_pending_irq; + tests[14] = r_mnxti_with_lower_lvl_pending_irq; + tests[15] = w_mnxti_side_effects; + tests[16] = rw_mscratchcsw; + tests[17] = rw_mscratchcsw_illegal; + tests[18] = rw_mscratchcswl; + tests[19] = rw_mscratchcswl_illegal; + tests[20] = mret_with_minhv; + tests[21] = mintthresh_lower; + tests[22] = mintthresh_higher; + tests[23] = mintthresh_equal; // Run all tests in list above cvprintf(V_LOW, "\nCLIC Test start\n\n"); @@ -1314,6 +1320,33 @@ __attribute__((naked)) void mtvt_code(void) { // ----------------------------------------------------------------------------- +__attribute__((naked)) void mtvt_code_destination_blocked(void) { + __asm__ volatile ( R"( + .global mtvt_table_mret + .global mtvt_table_mret_dest + .align 7 + mtvt_table_mret: .long . + 4096 + mtvt_table_mret_1: .long . + 4092 + mtvt_table_mret_2: .long . + 4088 + mtvt_table_mret_3: .long . + 4084 + mtvt_table_mret_4: .long . + 4080 + .space 100, 0x0 + mtvt_table_mret_30: .long . + 3976 + mtvt_table_mret_31: .long . + 3972 + mtvt_table_mret_32: .long . + 3968 + .space 3952, 0x0 + mtvt_table_mret_1021: .long . + 12 + mtvt_table_mret_1022: .long . + 8 + mtvt_table_mret_1023: .long . + 4 + + mtvt_table_mret_dest: jal zero, m_fast14_irq_handler + )" + ); +} + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + __attribute__((naked)) void m_fast14_irq_handler(void) { __asm__ volatile ( R"( # Push saved regs and allocate space for the remaining 16 regs @@ -1357,17 +1390,45 @@ __attribute__((naked)) void m_fast14_irq_handler(void) { # Check if we should skip jump to recovery code lw s0, g_recovery_enable lw s1, 0(s0) - beq s1, zero, 1f - add s1, zero, zero + beq s1, zero, 5f + + addi s2, zero, 1 + beq s1, s2, 1f + + addi s2, zero, 2 + beq s1, s2, 2f + + addi s2, zero, 3 + beq s1, s2, 3f + + # First test with recovery_pt + 1: add s1, zero, zero sw s1, 0(s0) - # Else, Get recovery mepc and replace mepc + # Get recovery mepc and replace mepc la s1, recovery_pt csrrw zero, mepc, s1 + jal zero, 4f + + # Second test with recovery_pt_mret + 2: add s1, zero, zero + sw s1, 0(s0) + # Get recovery mepc and replace mepc + la s1, recovery_pt_mret + csrrw zero, mepc, s1 + jal zero, 4f + + # Third test with recovery_pt_mret_ptr + 3: add s1, zero, zero + sw s1, 0(s0) + # Get recovery mepc and replace mepc + la s1, recovery_pt_mret_ptr + csrrw zero, mepc, s1 + # clear mcause, set mpp - lui s1, 0x30000 + 4: lui s1, 0x30000 csrrw zero, mcause, s1 - 1: + 5: ## restore stack lw gp, 64(sp) @@ -1555,9 +1616,205 @@ uint32_t invalid_mtvt_ptr_exec(uint32_t index, uint8_t report_name) { recovery_pt: add x0, x0, x0 )":::); - cvprintf(V_LOW, "Entered recovery point, due to unrecoverable clic ptr trap, mepc: %08x, expected: %08x\n", *g_mepc_triggered, (uint32_t)(*((&mtvt_table) + 4))); - test_fail += test_fail_asm || *g_mepc_triggered != (uint32_t)(*(&mtvt_table + 4)); + __asm__ volatile ( R"( + lui t0, 0x40000 + csrrc zero, mcause, t0 + )" ::: "t0"); + + cvprintf(V_LOW, "Entered recovery point, due to unrecoverable clic ptr trap, mepc: %08x, expected: %08x\n", *g_mepc_triggered, (uint32_t)(&mtvt_table + 4)); + test_fail += test_fail_asm || *g_mepc_triggered != (uint32_t)(&mtvt_table + 4); + + + if (test_fail) { + cvprintf(V_LOW, "\nTest: \"%s\" FAIL!\n", name); + return index + 1; + } + cvprintf(V_MEDIUM, "\nTest: \"%s\" OK!\n", name); + return 0; +} + +// ----------------------------------------------------------------------------- + +uint32_t invalid_mtvt_ptr_exec_mret(uint32_t index, uint8_t report_name) { + volatile uint8_t test_fail = 0; + + volatile uint32_t addr = 0x0; + + SET_FUNC_INFO + if (report_name) { + cvprintf(V_LOW, "\"%s\"", name); + return 0; + } + + // Set PMP configuration + __asm__ volatile ( R"( + la %[addr], mtvt_table_mret_dest + srli %[addr], %[addr], 2 + csrrw x0, pmpaddr0, %[addr] + la %[addr], mtvt_table_mret_dest + 4 + srli %[addr], %[addr], 2 + csrrw x0, pmpaddr1, %[addr] + addi %[addr], x0, -1 + csrrw x0, pmpaddr2, %[addr] + )" + : [addr] "+r"(addr) + : + : "t0" + ); + + set_mseccfg((mseccfg_t){ + .rlb = 1, + .mmwp = 0, + .mml = 0 + }); + + set_pmpcfg((pmpcfg_t){ + .reg_no = 0, + .lock = 0, + .mode = TOR, + .execute = 1, + .write = 1, + .read = 1 + }); + + set_pmpcfg((pmpcfg_t){ + .reg_no = 1, + .lock = 1, + .mode = TOR, + .execute = 0, + .write = 0, + .read = 0 + }); + + set_pmpcfg((pmpcfg_t){ + .reg_no = 2, + .lock = 0, + .mode = TOR, + .execute = 1, + .write = 1, + .read = 1 + }); + + *g_mepc_triggered = 0; + *g_recovery_enable = 2; + test_fail_asm = 0; + + __asm__ volatile ( R"( + la t0, mtvt_table_mret_4 + csrrw zero, mepc, t0 + # set minhv and mpp = M + lui t0, 0x70000 + csrrs zero, mcause, t0 + )"::: "t0"); + + __asm__ volatile ( R"( + mret + )":::); + + __asm__ volatile ( R"( + .extern test_fail_asm + # This should never execute (deliberate dead code) + la t0, test_fail_asm + lw t1, 0(t0) + addi t1, t1, 1 + sw t1, 0(t0) + # Execution should continue here + .global recovery_pt_mret + recovery_pt_mret: add x0, x0, x0 + )":::); + + __asm__ volatile ( R"( + lui t0, 0x40000 + csrrc zero, mcause, t0 + )" ::: "t0"); + + cvprintf(V_LOW, "Entered recovery point, due to unrecoverable mret ptr dest. trap, mepc: %08x, expected: %08x\n", *g_mepc_triggered, (uint32_t)(&mtvt_table_mret_dest)); + test_fail += test_fail_asm || *g_mepc_triggered != (uint32_t)(&mtvt_table_mret_dest); + + // Set PMP configuration + __asm__ volatile ( R"( + la %[addr], mtvt_table_mret_3 + srli %[addr], %[addr], 2 + csrrw x0, pmpaddr0, %[addr] + la %[addr], mtvt_table_mret_4 + srli %[addr], %[addr], 2 + csrrw x0, pmpaddr1, %[addr] + addi %[addr], x0, -1 + csrrw x0, pmpaddr2, %[addr] + )" + : [addr] "+r"(addr) + : + : "t0" + ); + set_mseccfg((mseccfg_t){ + .rlb = 1, + .mmwp = 0, + .mml = 0 + }); + + set_pmpcfg((pmpcfg_t){ + .reg_no = 0, + .lock = 0, + .mode = TOR, + .execute = 1, + .write = 1, + .read = 1 + }); + + set_pmpcfg((pmpcfg_t){ + .reg_no = 1, + .lock = 1, + .mode = TOR, + .execute = 0, + .write = 0, + .read = 0 + }); + + set_pmpcfg((pmpcfg_t){ + .reg_no = 2, + .lock = 0, + .mode = TOR, + .execute = 1, + .write = 1, + .read = 1 + }); + + *g_mepc_triggered = 0; + *g_recovery_enable = 3; + test_fail_asm = 0; + + __asm__ volatile ( R"( + la t0, mtvt_table_mret_3 + csrrw zero, mepc, t0 + # set minhv and mpp = M + lui t0, 0x70000 + csrrs zero, mcause, t0 + )"::: "t0"); + + __asm__ volatile ( R"( + mret + )":::); + + __asm__ volatile ( R"( + .extern test_fail_asm + # This should never execute (deliberate dead code) + la t0, test_fail_asm + lw t1, 0(t0) + addi t1, t1, 1 + sw t1, 0(t0) + # Execution should continue here + .global recovery_pt_mret_ptr + recovery_pt_mret_ptr: add x0, x0, x0 + )":::); + + __asm__ volatile ( R"( + lui t0, 0x40000 + csrrc zero, mcause, t0 + )" ::: "t0"); + + cvprintf(V_LOW, "Entered recovery point, due to unrecoverable mret ptr trap, mepc: %08x, expected: %08x\n", *g_mepc_triggered, (uint32_t)(&mtvt_table_mret + 3)); + test_fail += test_fail_asm || *g_mepc_triggered != (uint32_t)(&mtvt_table_mret + 3); if (test_fail) { cvprintf(V_LOW, "\nTest: \"%s\" FAIL!\n", name); @@ -1567,6 +1824,8 @@ uint32_t invalid_mtvt_ptr_exec(uint32_t index, uint8_t report_name) { return 0; } +// ----------------------------------------------------------------------------- + uint32_t r_mnxti_without_irq(uint32_t index, uint8_t report_name) { volatile uint8_t test_fail = 0; volatile uint32_t mnxti_rval = 0; @@ -3162,7 +3421,7 @@ __attribute__((interrupt("machine"))) void u_sw_irq_handler(void) { switch (mcause.clic.interrupt) { case 0: switch (mcause.clic.exccode) { - case 0x1: cvprintf(V_LOW, "Instruction access fault at 0x%08lx\n", mepc); + case 0x1: cvprintf(V_LOW, "Instruction access fault at 0x%08lx minhv: %0d\n", mepc, mcause.clic.minhv); break; case 0x2: cvprintf(V_LOW, "Invalid instruction fault at 0x%08lx\n", mepc); break; @@ -3177,9 +3436,7 @@ __attribute__((interrupt("machine"))) void u_sw_irq_handler(void) { // check if address is locked, then unlock // let test be responsible for cleaning up addr-regs to // not clutter code here - if ( /*mcause.clic.interrupt &&*/ mcause.clic.exccode == 1 && mcause.clic.minhv ) { - *g_recovery_enable = 1; - vp_assert_irq(0, 0); + if ( mcause.clic.exccode == 1 ) { cvprintf(V_LOW, "Encountered read access fault, trying to enable pmp access\n"); __asm__ volatile ( R"( csrrw x0, pmpcfg0, %[access_ena] @@ -3198,16 +3455,10 @@ __attribute__((interrupt("machine"))) void u_sw_irq_handler(void) { csrrw x0, pmpcfg13, %[access_ena] csrrw x0, pmpcfg14, %[access_ena] csrrw x0, pmpcfg15, %[access_ena] - - csrrs t0, mepc, x0 - lw t0, 0(t0) - lui t1, 0x40000 - csrrc x0, mcause, t1 - csrrw x0, mepc, t0 )" : : [access_ena] "r" (pmp_enable_access_all) - : "t0", "t1" + : ); } diff --git a/cv32e40s/tests/programs/custom/debug_test2/debug_test2.c b/cv32e40s/tests/programs/custom/debug_test2/debug_test2.c index 6795dad584..27a9cc7110 100644 --- a/cv32e40s/tests/programs/custom/debug_test2/debug_test2.c +++ b/cv32e40s/tests/programs/custom/debug_test2/debug_test2.c @@ -33,7 +33,7 @@ // MUST be 31 or less (bit position-1 in result array determines test pass/fail // status, thus we are limited to 31 tests with this construct. -#define NUM_TESTS 19 +#define NUM_TESTS 21 // Start at 1 (ignore dummy test that is only used for env sanity checking during dev.) #define START_TEST_NUM 1 // Abort test at first self-check fail, useful for debugging. @@ -379,6 +379,8 @@ volatile uint32_t * volatile g_trigger_matched; volatile uint32_t * volatile g_has_clic; volatile uint32_t * volatile g_single_step_unspec_err; +volatile uint32_t g_pushpop_area [64]; + extern volatile uint32_t *trigger_loc; extern volatile uint32_t *trigger_loc_dbg; extern volatile uint32_t *trigger_exit; @@ -465,6 +467,8 @@ uint32_t check_stopcnt_bits(uint32_t index, uint8_t report_name); uint32_t single_step(uint32_t index, uint8_t report_name); uint32_t mprv_dret_to_umode(uint32_t index, uint8_t report_name); uint32_t cover_known_iss_mismatches(uint32_t index, uint8_t report_name); +uint32_t push_haltreq(uint32_t index, uint8_t report_name); +uint32_t pop_haltreq(uint32_t index, uint8_t report_name); // --------------------------------------------------------------- // Prototypes for functions that are test specific and @@ -621,7 +625,7 @@ int main(int argc, char **argv){ setup_clic(); // Add function pointers to new tests here - tests[0] = dummy; // unused, can be used for env sanity checking + tests[0] = dummy; // unused, can be used for env sanity checking tests[1] = debug_csr_rw; tests[2] = trigger_default_val; tests[3] = ebreak_behavior_m_mode; @@ -640,6 +644,8 @@ int main(int argc, char **argv){ tests[16] = single_step; tests[17] = mprv_dret_to_umode; tests[18] = cover_known_iss_mismatches; + tests[19] = push_haltreq; + tests[20] = pop_haltreq; // Run all tests in list above cvprintf(V_LOW, "\nDebug test start\n\n"); @@ -1134,6 +1140,115 @@ uint32_t request_ebreak_3x(uint32_t index, uint8_t report_name) { // ----------------------------------------------------------------------------- +uint32_t push_haltreq(uint32_t index, uint8_t report_name) { + volatile uint8_t test_fail = 0; + volatile debug_req_control_t debug_req_ctrl; + + SET_FUNC_INFO + + if (report_name) { + cvprintf(V_LOW, "\"%s\"", name); + return 0; + } + + debug_req_ctrl = (debug_req_control_t) { + .fields.value = 1, + .fields.pulse_mode = 1, + .fields.rand_pulse_width = 0, + .fields.pulse_width = 0x1fff, + .fields.rand_start_delay = 0, + .fields.start_delay = 15 + }; + + *g_debug_test_num = 19; + *g_debug_status = 0; + DEBUG_REQ_CONTROL_REG = debug_req_ctrl.raw; + + __asm__ volatile( + R"( + # Save old "sp" + mv t0, sp + + # Setup temporary "sp" + la sp, g_pushpop_area + addi sp, sp, 64 + + # Push to temporary "sp" + cm.push {x1, x8-x9, x18-x27}, -64 + + # Restore old "sp" + mv sp, t0 + )"::: "t0" + ); + + test_fail += *g_debug_status == 1 ? 0 : 1; + *g_debug_status = 0; + + if (test_fail) { + cvprintf(V_LOW, "\nTest: \"%s\" FAIL!\n", name); + return index + 1; + } + cvprintf(V_LOW, "\nTest: \"%s\" OK!\n", name); + return 0; +} + + +// ----------------------------------------------------------------------------- + +uint32_t pop_haltreq(uint32_t index, uint8_t report_name) { + volatile uint8_t test_fail = 0; + volatile debug_req_control_t debug_req_ctrl; + + SET_FUNC_INFO + + if (report_name) { + cvprintf(V_LOW, "\"%s\"", name); + return 0; + } + + debug_req_ctrl = (debug_req_control_t) { + .fields.value = 1, + .fields.pulse_mode = 1, + .fields.rand_pulse_width = 0, + .fields.pulse_width = 0x1fff, + .fields.rand_start_delay = 0, + .fields.start_delay = 25 + }; + + *g_debug_test_num = 20; + *g_debug_status = 0; + DEBUG_REQ_CONTROL_REG = debug_req_ctrl.raw; + + __asm__ volatile( + R"( + # Save old "sp" and GPRs + cm.push {x1, x8-x9}, -16 + mv t0, sp + + # Setup temporary "sp" + la sp, g_pushpop_area + + # Pop from temporary "sp" + cm.pop {x1, x8-x9, x18-x27}, 64 + + # Restore old "sp" and GPRs + mv sp, t0 + cm.pop {x1, x8-x9}, 16 + )"::: "t0" + ); + + test_fail += *g_debug_status == 1 ? 0 : 1; + *g_debug_status = 0; + + if (test_fail) { + cvprintf(V_LOW, "\nTest: \"%s\" FAIL!\n", name); + return index + 1; + } + cvprintf(V_LOW, "\nTest: \"%s\" OK!\n", name); + return 0; +} +// ----------------------------------------------------------------------------- + __attribute__((naked)) void m_fast14_irq_handler(void) { __asm__ volatile ( R"( @@ -1455,6 +1570,10 @@ void __attribute__((naked)) _debugger_start(void) { beq s0, s1, 14f addi s0, zero, 18 beq s0, s1, 18f + addi s0, zero, 19 + beq s0, s1, 19f + addi s0, zero, 20 + beq s0, s1, 20f # no match, exit beq zero, zero, 99f @@ -1498,6 +1617,12 @@ void __attribute__((naked)) _debugger_start(void) { 18: call cover_known_iss_mismatches_dbg beq zero, zero, 99f + 19: call request_hw_debugger_dbg + beq zero, zero, 99f + + 20: call request_hw_debugger_dbg + beq zero, zero, 99f + 99: call _debugger_end dret diff --git a/cv32e40s/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c b/cv32e40s/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c new file mode 100644 index 0000000000..5cc0039faf --- /dev/null +++ b/cv32e40s/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c @@ -0,0 +1,244 @@ +// Copyright 2023 Silicon Labs, Inc. +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may +// not use this file except in compliance with the License, or, at your option, +// the Apache License version 2.0. +// +// You may obtain a copy of the License at +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// 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. + +#include +#include +#include + + +int write_mhpmcounters() +{ + uint32_t reg = 0; + __asm__ volatile("mv %0, x0" : "=r"(reg)); + __asm__ volatile("not %0, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter3, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter4, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter5, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter6, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter7, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter8, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter9, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter10, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter11, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter12, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter13, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter14, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter15, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter16, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter17, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter18, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter19, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter20, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter21, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter22, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter23, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter24, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter25, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter26, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter27, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter28, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter29, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter30, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter31, %0" :: "r"(reg)); + + return 0; +} + +int write_mhpmcounterhs() +{ + uint32_t reg = 0; + __asm__ volatile("mv %0, x0" : "=r"(reg)); + __asm__ volatile("not %0, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter3h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter4h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter5h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter6h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter7h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter8h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter9h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter10h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter11h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter12h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter13h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter14h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter15h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter16h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter17h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter18h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter19h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter20h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter21h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter22h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter23h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter24h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter25h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter26h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter27h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter28h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter29h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter30h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter31h, %0" :: "r"(reg)); + + return 0; +} + +int check_mhpmcounters_are_zero() +{ + uint32_t reg = 0; + __asm__ volatile("csrr %0, mhpmcounter3" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter4" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter5" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter6" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter7" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter8" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter9" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter10" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter11" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter12" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter13" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter14" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter15" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter16" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter17" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter18" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter19" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter20" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter21" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter22" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter23" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter24" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter25" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter26" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter27" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter28" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter29" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter30" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter31" : "=r"(reg)); + if(reg != 0) return 1; + + return 0; +} + +int check_mhpmcounterhs_are_zero() +{ + uint32_t reg = 0; + __asm__ volatile("csrr %0, mhpmcounter3h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter4h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter5h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter6h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter7h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter8h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter9h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter10h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter11h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter12h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter13h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter14h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter15h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter16h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter17h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter18h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter19h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter20h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter21h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter22h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter23h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter24h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter25h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter26h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter27h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter28h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter29h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter30h" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, mhpmcounter31h" : "=r"(reg)); + if(reg != 0) return 1; + + return 0; +} + + +int main() +{ + uint32_t is_failure = 0; + + write_mhpmcounters(); + write_mhpmcounterhs(); + + is_failure += check_mhpmcounters_are_zero(); + is_failure += check_mhpmcounterhs_are_zero(); + + if (is_failure) return EXIT_FAILURE; + return EXIT_SUCCESS; + +} diff --git a/cv32e40s/tests/programs/custom/mhpmcounter_write_test/test.yaml b/cv32e40s/tests/programs/custom/mhpmcounter_write_test/test.yaml new file mode 100644 index 0000000000..9f061158d5 --- /dev/null +++ b/cv32e40s/tests/programs/custom/mhpmcounter_write_test/test.yaml @@ -0,0 +1,4 @@ +name: mhpmcounter_write_test +uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c +description: > + Write to mhpmcounters. Is only verifyed by ISS, should be verifyed that we get excpected behaviour? diff --git a/cv32e40s/tests/programs/custom/minhv_pma_block/minhv_pma_block.c b/cv32e40s/tests/programs/custom/minhv_pma_block/minhv_pma_block.c new file mode 100644 index 0000000000..cafc28a3ff --- /dev/null +++ b/cv32e40s/tests/programs/custom/minhv_pma_block/minhv_pma_block.c @@ -0,0 +1,172 @@ +// +// Copyright 2023 Silicon Labs, Inc. +// +// Licensed under the Solderpad Hardware Licence, 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 +// +// https://solderpad.org/licenses/ +// +// 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. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Author: Kristine Døsvik +// +// Test minhv=1 and pma block of mepc address. +// +///////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "bsp.h" + +#define RND_ADDRS_IN_PMA_CFG_2_IO_REGION 0xE0100010 + +extern volatile uint32_t recovery_pt_mret; +volatile uint32_t g_entered_trap_handler; +volatile uint32_t g_trapped_mcause; + +int execute_from_io_region(); +__attribute__((interrupt ("machine"))) void u_sw_irq_handler(void); +void trap_handler(void); + + +int main(int argc, char **argv){ + + int is_failure = 0; + + is_failure += execute_from_io_region(); + + if(is_failure){ + return EXIT_FAILURE; + } else { + return EXIT_SUCCESS; + } +} + + +int execute_from_io_region() { + + volatile uint32_t io_addr = RND_ADDRS_IN_PMA_CFG_2_IO_REGION; + volatile uint32_t mcause_excode = 0x0; + volatile uint32_t mcause_excode_expected = EXC_CAUSE_INSTR_ACC_FAULT; //Execution attempt from I/O region. + volatile uint32_t mret_dont_trap = 0; + volatile uint32_t test_fail = 0; + g_entered_trap_handler = 0; + + // Load an IO memory address into mepc + __asm__ volatile ( R"( + csrrw zero, mepc, %[io_addr] + )" :: [io_addr] "r"(io_addr)); + + // Set minhv and mpp = M + __asm__ volatile ( R"( + lui t0, 0x70000 + csrrs zero, mcause, t0 + )"::: "t0"); + + __asm__ volatile ( R"( + mret + )":::); + + // Mret traps. + + // This should never execute (deliberate dead code), as the mret make the pc take a jump + mret_dont_trap += 1; + + // Execution should continue here + __asm__ volatile ( R"( + .global recovery_pt_mret + recovery_pt_mret: add x0, x0, x0 + )":::); + + + mcause_excode = g_trapped_mcause & 0x7ff; + + printf("Mret traps: %08lx, expected: 1\n", g_entered_trap_handler); + printf("Mret dont trap: %08lx, expected: 0\n", mret_dont_trap); + printf("mcause excode: %08lx, expected: %08lx (execution attempt from I/O region).\n", mcause_excode, mcause_excode_expected); + test_fail += (g_entered_trap_handler != 1) || mret_dont_trap || (mcause_excode != mcause_excode_expected); + + printf("g_trapped_mcause: %08lx", g_trapped_mcause); + + return test_fail; +} + + +__attribute__((interrupt ("machine"))) +void u_sw_irq_handler(void) { + __asm__ volatile (R"( + # Backup all GPRs + sw a0, -4(sp) + sw a1, -8(sp) + sw a2, -12(sp) + sw a3, -16(sp) + sw a4, -20(sp) + sw a5, -24(sp) + sw a6, -28(sp) + sw a7, -32(sp) + sw t0, -36(sp) + sw t1, -40(sp) + sw t2, -44(sp) + sw t3, -48(sp) + sw t4, -52(sp) + sw t5, -56(sp) + sw t6, -60(sp) + addi sp, sp, -64 + cm.push {ra, s0-s11}, -64 + + # Call the handler actual + call ra, trap_handler + + # Restore all GPRs + cm.pop {ra, s0-s11}, 64 + addi sp, sp, 64 + lw a0, -4(sp) + lw a1, -8(sp) + lw a2, -12(sp) + lw a3, -16(sp) + lw a4, -20(sp) + lw a5, -24(sp) + lw a6, -28(sp) + lw a7, -32(sp) + lw t0, -36(sp) + lw t1, -40(sp) + lw t2, -44(sp) + lw t3, -48(sp) + lw t4, -52(sp) + lw t5, -56(sp) + lw t6, -60(sp) + + # Restore "sp" + # csrr sp, dscratch0 + + # Done + mret + )"); +} + +void trap_handler(void) { + + g_entered_trap_handler += 1; + + __asm__ volatile ( R"( + # Get recovery mepc and replace mepc + la t0, recovery_pt_mret + csrrw zero, mepc, t0 + + # read and clear mcause except mpp, which is set + 4: lui t0, 0x30000 + csrrw %[g_trapped_mcause], mcause, t0 + + )" : [g_trapped_mcause]"=r"(g_trapped_mcause) :: "t0"); + + return; +} + diff --git a/cv32e40s/tests/programs/custom/minhv_pma_block/test.yaml b/cv32e40s/tests/programs/custom/minhv_pma_block/test.yaml new file mode 100644 index 0000000000..4f43e93d63 --- /dev/null +++ b/cv32e40s/tests/programs/custom/minhv_pma_block/test.yaml @@ -0,0 +1,8 @@ +name: minhv_pma_block +uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c +description: > + Use CFG=p,a_test_cfg_2. Test minhv=1 and pma block of mepc address +plusargs: > + +clic_irq_clear_on_ack=0 +cflags: > + -mno-relax diff --git a/cv32e40s/tests/programs/custom/pma/pma.c b/cv32e40s/tests/programs/custom/pma/pma.c index 36f0e99274..52dabc85fc 100644 --- a/cv32e40s/tests/programs/custom/pma/pma.c +++ b/cv32e40s/tests/programs/custom/pma/pma.c @@ -31,7 +31,7 @@ // MUST be 31 or less (bit position-1 in result array determines test pass/fail // status, thus we are limited to 31 tests with this construct. -#define NUM_TESTS 9 +#define NUM_TESTS 11 // Start at 1 (ignore dummy test that is only used for env sanity checking during dev.) #define START_TEST_NUM 1 // Abort test at first self-check fail, useful for debugging. @@ -160,6 +160,8 @@ uint32_t misaligned_border_io_to_mem(uint32_t index, uint8_t report_name); uint32_t misaligned_border_mem_to_io(uint32_t index, uint8_t report_name); uint32_t misalign_store_fault_no_bus_access_second(uint32_t index, uint8_t report_name); uint32_t misalign_store_fault_io_no_bus_access_first(uint32_t index, uint8_t report_name); +uint32_t push_border(uint32_t index, uint8_t report_name); +uint32_t pop_border(uint32_t index, uint8_t report_name); // --------------------------------------------------------------- // Prototypes for functions that are test specific and @@ -218,6 +220,11 @@ int cvprintf(verbosity_t verbosity, const char *format, ...) __attribute((__noin // Test entry point // --------------------------------------------------------------- int main(int argc, char **argv){ + // need to use a different stack for the exception handlers, due to testing push/pop + __asm__ volatile (R"( + la t0, __debugger_stack_start + csrw mscratch, t0 + )"); volatile uint32_t (* volatile tests[NUM_TESTS])(volatile uint32_t, volatile uint8_t); volatile uint32_t test_res = 0x1; @@ -237,15 +244,17 @@ int main(int argc, char **argv){ setup_clic(); // Add function pointers to new tests here - tests[0] = dummy; // unused, can be used for env sanity checking - tests[1] = exec_only_for_main_regions; - tests[2] = non_natural_aligned_store_to_io; - tests[3] = non_natural_aligned_loads_from_io; - tests[4] = misaligned_fault_nochange_regfile; - tests[5] = misaligned_border_io_to_mem; - tests[6] = misaligned_border_mem_to_io; - tests[7] = misalign_store_fault_no_bus_access_second; - tests[8] = misalign_store_fault_io_no_bus_access_first; + tests[0] = dummy; // unused, can be used for env sanity checking + tests[1] = exec_only_for_main_regions; + tests[2] = non_natural_aligned_store_to_io; + tests[3] = non_natural_aligned_loads_from_io; + tests[4] = misaligned_fault_nochange_regfile; + tests[5] = misaligned_border_io_to_mem; + tests[6] = misaligned_border_mem_to_io; + tests[7] = misalign_store_fault_no_bus_access_second; + tests[8] = misalign_store_fault_io_no_bus_access_first; + tests[9] = push_border; + tests[10] = pop_border; // Run all tests in list above cvprintf(V_LOW, "\nPMA test start\n\n"); for (volatile uint32_t i = START_TEST_NUM; i < NUM_TESTS; i++) { @@ -750,6 +759,102 @@ uint32_t misaligned_border_mem_to_io(uint32_t index, uint8_t report_name) { // ----------------------------------------------------------------------------- +uint32_t push_border(uint32_t index, uint8_t report_name) { + volatile uint32_t test_fail = 0; + volatile uint32_t io_addr = 0x1a111000; + + SET_FUNC_INFO + + if (report_name) { + cvprintf(V_LOW, "\"%s\"", name); + return 0; + } + + *g_test_num = index; + + *g_exp_fault = 1; + + __asm__ volatile(R"( + # Save old "sp" + mv t0, sp + + # Setup temporary "sp" push should pass IO border + mv sp, %[addr] + addi sp, sp, 8 + + # Push to temporary "sp" + cm.push {x1, x8-x9}, -16 + + # Restore old "sp" + mv sp, t0 + )" + :: [addr] "r"(io_addr) + : "t0", "memory" + ); + + + test_fail += *g_exp_fault; + clear_status_csrs(); + + if (test_fail) { + cvprintf(V_LOW, "\nTest: \"%s\" FAIL!\n", name); + return index + 1; + } + cvprintf(V_LOW, "\nTest: \"%s\" OK!\n", name); + return 0; +} + + +// ----------------------------------------------------------------------------- + +uint32_t pop_border(uint32_t index, uint8_t report_name) { + volatile uint32_t test_fail = 0; + volatile uint32_t io_addr = 0x1a110810; + + SET_FUNC_INFO + + if (report_name) { + cvprintf(V_LOW, "\"%s\"", name); + return 0; + } + + *g_test_num = index; + + *g_exp_fault = 1; + + __asm__ volatile( + R"( + # Save old "sp" and GPRs + cm.push {x1, x8-x9}, -16 + mv t0, sp + + # Setup temporary "sp" pop should pass IO border + mv sp, %[addr] + addi sp, sp, -8 + + # Pop from temporary "sp" + cm.pop {x1, x8-x9}, 16 + + # Restore old "sp" and GPRs + mv sp, t0 + cm.pop {x1, x8-x9}, 16 + )" + :: [addr] "r"(io_addr) + : "t0", "memory" + ); + + test_fail += *g_exp_fault; + clear_status_csrs(); + + if (test_fail) { + cvprintf(V_LOW, "\nTest: \"%s\" FAIL!\n", name); + return index + 1; + } + cvprintf(V_LOW, "\nTest: \"%s\" OK!\n", name); + return 0; +} +// ----------------------------------------------------------------------------- + uint32_t misalign_store_fault_no_bus_access_second(uint32_t index, uint8_t report_name) { volatile uint32_t test_fail = 0; volatile uint32_t io_addr = 0x1a110810; @@ -1055,6 +1160,9 @@ uint32_t detect_irq_mode(void) { void __attribute__((naked)) u_sw_irq_handler(void) { __asm__ volatile (R"( .extern u_sw_irq_handler_normal + + csrrw sp, mscratch, sp + cm.push {ra, s0-s11}, -112 addi sp, sp, -12 @@ -1116,6 +1224,9 @@ void __attribute__((naked)) u_sw_irq_handler(void) { # Restore stack ptr addi sp, sp, 12 cm.pop {ra, s0-s11}, 112 + + csrrw sp, mscratch, sp + mret )"); @@ -1146,7 +1257,7 @@ void u_sw_irq_handler_normal(void) { csrrw zero, mepc, t0 )" ::: "t0", "memory"); } - else if (*g_test_num >= 2 && *g_test_num <= 9) { + else if (*g_test_num >= 2 && *g_test_num <= 11) { increment_mepc(0); if (*g_exp_fault) { *g_exp_fault = 0; diff --git a/cv32e40s/tests/programs/custom/pushpop_debug_triggers/pushpop_debug_triggers.c b/cv32e40s/tests/programs/custom/pushpop_debug_triggers/pushpop_debug_triggers.c index aca7c7a4d3..e0881c7e25 100644 --- a/cv32e40s/tests/programs/custom/pushpop_debug_triggers/pushpop_debug_triggers.c +++ b/cv32e40s/tests/programs/custom/pushpop_debug_triggers/pushpop_debug_triggers.c @@ -33,6 +33,7 @@ volatile uint32_t g_debug_function_setup_triggers = 0; volatile uint32_t g_exception_expected = 0; volatile uint32_t g_pushpop_area [32]; +volatile uint32_t g_pushpop_area_index = 0; void disable_debug_req(void) { CV_VP_DEBUG_CONTROL = ( @@ -111,7 +112,7 @@ void debug_start(void) { )"); } -static void setup_triggers(void){ +static void setup_triggers(int index){ mcontrol6_t mcontrol6; uint32_t trigger_addr; @@ -122,7 +123,7 @@ static void setup_triggers(void){ mcontrol6.fields.match = 0; // (match exact address) mcontrol6.fields.type = 6; - trigger_addr = (uint32_t) &(g_pushpop_area[2]); // (arbitrary index) + trigger_addr = (uint32_t) &(g_pushpop_area[index]); __asm__ volatile( R"( @@ -180,7 +181,7 @@ void debug_handler(void){ if (g_debug_function_setup_triggers) { g_debug_function_setup_triggers = 0; - setup_triggers(); + setup_triggers(g_pushpop_area_index); return; } if (g_debug_function_incr_dpc) { @@ -238,12 +239,13 @@ static void pop_debug_trigger(void){ ); } -static void let_dmode_setup_triggers(void){ +static void let_dmode_setup_triggers(int index){ printf("setup trigs\n"); g_debug_expected = 1; g_debug_entered = 0; g_debug_function_setup_triggers = 1; + g_pushpop_area_index = index; // Prolonged pulse duration so debug req has a chance to be acked and taken CV_VP_DEBUG_CONTROL = ( @@ -293,7 +295,13 @@ static void test_pop_debug_trigger(void){ } int main(int argc, char **argv){ - let_dmode_setup_triggers(); + let_dmode_setup_triggers(2); + test_push_debug_trigger(); + test_pop_debug_trigger(); + let_dmode_setup_triggers(1); // trigger at last address in actual sequence + test_push_debug_trigger(); + test_pop_debug_trigger(); + let_dmode_setup_triggers(3); // trigger at first address in actual sequence test_push_debug_trigger(); test_pop_debug_trigger(); diff --git a/cv32e40s/tests/programs/custom/zc_test/zc_test.c b/cv32e40s/tests/programs/custom/zc_test/zc_test.c index 3bac064f27..34c751b673 100644 --- a/cv32e40s/tests/programs/custom/zc_test/zc_test.c +++ b/cv32e40s/tests/programs/custom/zc_test/zc_test.c @@ -111,6 +111,17 @@ void m_external_irq_handler(void) { } +static void +test_mva01s_same_register(void) +{ + printf("test_mva01s_same_register: start\n"); + __asm__ volatile( + "cm.mva01s s2, s2" + : : : "s2" + ); + printf("test_mva01s_same_register: done\n"); +} + int main(int argc, char *argv[]) { @@ -120,10 +131,15 @@ int main(int argc, char *argv[]) test_instr_num = 0; + // Setup + printf("Enabling irq. \n"); enable_all_irq(); + + // Test: PushPop + printf("\n\nTesting push/pop instructions. \n"); test_active = pushpop; @@ -138,11 +154,13 @@ int main(int argc, char *argv[]) interrupt_push_pop(i); } + + // Test: Popret + printf("\n\nTesting popret instructions. \n"); test_active = popret; test_instr_num = 0; - for (int i = PUSH_RLIST_MIN; i <= PUSH_RLIST_MAX; i++) { glb_irq_line = 0x1 << EX_IRQ_LINE; @@ -154,11 +172,13 @@ int main(int argc, char *argv[]) interrupt_popret(i); } + + // Test: Popretz + printf("\n\nTesting popretz instructions. \n"); test_active = popretz; test_instr_num = 0; - for (int i = PUSH_RLIST_MIN; i <= PUSH_RLIST_MAX; i++) { glb_irq_line = 0x1 << EX_IRQ_LINE; @@ -171,6 +191,8 @@ int main(int argc, char *argv[]) } + // Test: Mvsa01 + printf("\n\nTesting mvsa01 instructions. \n"); test_active = mvsa; test_instr_num = 0; @@ -191,12 +213,18 @@ int main(int argc, char *argv[]) i = iteratorVault; } + + // Test: Mva01s + printf("\n\nTesting mva01s instructions. \n"); + test_active = mvas; test_instr_num = 0; + //creating random values for the target registers rnd0 = vp_random_num(0xFFFFFFFE, 0x0); rnd1 = vp_random_num(0xFFFFFFFE, 0x0); + for (int i = 0; i < MVAS_INSTR_SIZE; i++) { glb_irq_line = 0x1 << EX_IRQ_LINE; @@ -212,6 +240,13 @@ int main(int argc, char *argv[]) } + // Test: Mva01s - Same Register (Sanity check of RTL bugfix.) + + test_mva01s_same_register(); + + + // ErrorCheck & Exit + if(exp_irq != ex_traps_entered) { printf("\tERROR: %u interrupts taken, expected %u", (unsigned int)ex_traps_entered, (unsigned int)exp_irq); failureCount += 1; diff --git a/cv32e40s/tests/programs/custom/zcmt_test/zcmt_test.c b/cv32e40s/tests/programs/custom/zcmt_test/zcmt_test.c index 1ae81f0bb1..2713a95e5f 100644 --- a/cv32e40s/tests/programs/custom/zcmt_test/zcmt_test.c +++ b/cv32e40s/tests/programs/custom/zcmt_test/zcmt_test.c @@ -31,7 +31,7 @@ // MUST be 31 or less (bit position-1 in result array determines test pass/fail // status, thus we are limited to 31 tests with this construct. -#define NUM_TESTS 11 +#define NUM_TESTS 13 // Set which test index to start testing at (for quickly running specific tests during development) #define START_TEST_IDX 0 @@ -59,6 +59,8 @@ #define MSECCFG_ADDR 0x747 #define PMPCFG0_ADDR 0x3a0 #define PMPADDR0_ADDR 0x3b0 +#define PMPADDR1_ADDR 0x3b1 +#define PMPADDR2_ADDR 0x3b2 #define JVT_ADDR 0x017 @@ -101,6 +103,8 @@ uint32_t cm_jt_u_illegal(uint32_t index, uint8_t report_name); uint32_t cm_jalt_u_illegal(uint32_t index, uint8_t report_name); uint32_t cm_jt_u_legal(uint32_t index, uint8_t report_name); uint32_t cm_jalt_u_legal(uint32_t index, uint8_t report_name); +uint32_t cm_jt_m_trap(uint32_t index, uint8_t report_name); +uint32_t cm_jalt_m_trap(uint32_t index, uint8_t report_name); // --------------------------------------------------------------- // Generic test template: @@ -200,6 +204,7 @@ uint32_t has_pmp_configured(void); * Non-standard illegal instruction and ecall handlers */ void handle_illegal_insn(void); +void handle_insn_access_fault(void); void handle_ecall(void); void handle_ecall_u(void); @@ -232,11 +237,12 @@ int main(int argc, char **argv){ tests[8] = cm_jalt_u_illegal; tests[9] = cm_jt_u_legal; tests[10] = cm_jalt_u_legal; + tests[11] = cm_jt_m_trap; + tests[12] = cm_jalt_m_trap; // TODO silabs-hfegran: defering these tests to a later PR //tests[11] = cm_jt_m_trap_m; //tests[12] = cm_jt_u_trap_u; - //tests[11] = cm_jalt_m_trap; //tests[12] = cm_jalt_u_trap; // Run all tests in list above @@ -569,11 +575,12 @@ __attribute__((naked)) void jvt_code(void) { jvt_table: index_0: .word(jvt_index_0) index_1: .word(jvt_index_1) - .space 116, 0x0 + index_2: .word(jvt_index_2) + .space 112, 0x0 index_31: .word(jvt_index_31) index_32: .word(jvt_index_32) .space 8 - index_35: nop + index_35: .word(jvt_index_35) .space 172, 0x0 index_79: .word(jvt_index_79) .space 172, 0x0 @@ -621,6 +628,28 @@ __attribute__((optimize("align-functions=4"), naked)) void jvt_index_1(void) { // ----------------------------------------------------------------------------- +__attribute__((optimize("align-functions=4"), naked)) void jvt_index_2(void) { + __asm__ volatile ( R"( + addi sp, sp, -8 + sw a0, 0(sp) + sw a1, 4(sp) + + lw a0, g_expect_tablejmp + lw a1, 0(a0) + addi a1, a1, -2 + sw a1, 0(a0) + + lw a1, 4(sp) + lw a0, 0(sp) + addi sp, sp, 8 + lw a0, g_recovery_cm_jt + lw a0, 0(a0) + jalr zero, 0(a0) + )"); +} + +// ----------------------------------------------------------------------------- + __attribute__((optimize("align-functions=4"), naked)) void jvt_index_31(void) { __asm__ volatile ( R"( addi sp, sp, -8 @@ -666,6 +695,26 @@ __attribute__((optimize("align-functions=4"), naked)) void jvt_index_32(void) { // ----------------------------------------------------------------------------- +__attribute__((optimize("align-functions=4"), naked)) void jvt_index_35(void) { + __asm__ volatile ( R"( + addi sp, sp, -8 + sw a0, 0(sp) + sw a1, 4(sp) + + lw a0, g_expect_tablejmp + lw a1, 0(a0) + addi a1, a1, -35 + sw a1, 0(a0) + + lw a1, 4(sp) + lw a0, 0(sp) + addi sp, sp, 8 + ret + )"); +} + +// ----------------------------------------------------------------------------- + __attribute__((optimize("align-functions=4"), naked)) void jvt_index_79(void) { __asm__ volatile ( R"( addi sp, sp, -8 @@ -1742,3 +1791,220 @@ uint32_t cm_jalt_u_legal(uint32_t index, uint8_t report_name){ return 0; } +// ----------------------------------------------------------------------------- + +uint32_t cm_jt_m_trap(uint32_t index, uint8_t report_name){ + volatile uint8_t test_fail = 0; + volatile mseccfg_t mseccfg = { 0 }; + + SET_FUNC_INFO + + if (report_name) { + cvprintf(V_LOW, "\"%s\"", name); + return 0; + } + + (void)csr_instr(CSRRW, JVT_ADDR, ((uint32_t)&jvt_table)); + + mseccfg.fields.rlb = 1; + (void)csr_instr(CSRRW, MSECCFG_ADDR, mseccfg.raw); + + set_pmpcfg((pmpsubcfg_t){ + .fields.r = 1, + .fields.w = 1, + .fields.x = 1, + .fields.a = PMPMODE_TOR, + .fields.l = 0 + }, 0); + + set_pmpcfg((pmpsubcfg_t){ + .fields.r = 0, + .fields.w = 0, + .fields.x = 0, + .fields.a = PMPMODE_TOR, + .fields.l = 1 + }, 1); + + set_pmpcfg((pmpsubcfg_t){ + .fields.r = 1, + .fields.w = 1, + .fields.x = 1, + .fields.a = PMPMODE_TOR, + .fields.l = 0 + }, 2); + + // Set PMP configuration (lock down index 2 in table) + (void)csr_instr(CSRRW, PMPADDR0_ADDR, ((uint32_t)&jvt_table + 2*4) >> 2); + (void)csr_instr(CSRRW, PMPADDR1_ADDR, ((uint32_t)&jvt_table + 3*4) >> 2); + (void)csr_instr(CSRRW, PMPADDR2_ADDR, 0xffffffffUL >> 2); + + *g_expect_tablejmp = 2; + __asm__ volatile ( R"( + .global recovery_cm_jt_m_2 + addi sp, sp, -12 + sw a0, 0(sp) + sw a1, 4(sp) + sw a2, 8(sp) + + lw a0, g_recovery_cm_jt + la a1, recovery_cm_jt_m_2 + sw a1, 0(a0) + + cm.jt 2 + recovery_cm_jt_m_2: + lw a2, 8(sp) + lw a1, 4(sp) + lw a0, 0(sp) + + addi sp, sp, 12 + )"); + + test_fail += (*g_expect_tablejmp != 0) ? 1 : 0; + if (test_fail) { + // Should never be here in this test case unless something goes really wrong + cvprintf(V_LOW, "\nTest: \"%s\" FAIL!\n", name); + return index + 1; + } + cvprintf(V_MEDIUM, "\nTest: \"%s\" No self checking in this test, OK!\n", name); + return 0; +} + +// ----------------------------------------------------------------------------- + +uint32_t cm_jalt_m_trap(uint32_t index, uint8_t report_name){ + volatile uint8_t test_fail = 0; + volatile mseccfg_t mseccfg = { 0 }; + + SET_FUNC_INFO + + if (report_name) { + cvprintf(V_LOW, "\"%s\"", name); + return 0; + } + + (void)csr_instr(CSRRW, JVT_ADDR, ((uint32_t)&jvt_table)); + + mseccfg.fields.rlb = 1; + (void)csr_instr(CSRRW, MSECCFG_ADDR, mseccfg.raw); + + set_pmpcfg((pmpsubcfg_t){ + .fields.r = 1, + .fields.w = 1, + .fields.x = 1, + .fields.a = PMPMODE_TOR, + .fields.l = 0 + }, 0); + + set_pmpcfg((pmpsubcfg_t){ + .fields.r = 0, + .fields.w = 0, + .fields.x = 0, + .fields.a = PMPMODE_TOR, + .fields.l = 1 + }, 1); + + set_pmpcfg((pmpsubcfg_t){ + .fields.r = 1, + .fields.w = 1, + .fields.x = 1, + .fields.a = PMPMODE_TOR, + .fields.l = 0 + }, 2); + + // Set PMP configuration (lock down index 2 in table) + (void)csr_instr(CSRRW, PMPADDR0_ADDR, ((uint32_t)&jvt_table + 35*4) >> 2); + (void)csr_instr(CSRRW, PMPADDR1_ADDR, ((uint32_t)&jvt_table + 36*4) >> 2); + (void)csr_instr(CSRRW, PMPADDR2_ADDR, 0xffffffffUL >> 2); + + *g_expect_tablejmp = 35; + __asm__ volatile ( R"( + cm.jalt 35 + )"); + + test_fail += (*g_expect_tablejmp != 0) ? 1 : 0; + if (test_fail) { + // Should never be here in this test case unless something goes really wrong + cvprintf(V_LOW, "\nTest: \"%s\" FAIL!\n", name); + return index + 1; + } + cvprintf(V_MEDIUM, "\nTest: \"%s\" No self checking in this test, OK!\n", name); + return 0; +} + +// ----------------------------------------------------------------------------- + +__attribute__((naked)) void handle_insn_access_fault(void) { + __asm__ volatile ( R"( + call handle_insn_access_fault_code + j end_handler_ret + )"); +} + +// ----------------------------------------------------------------------------- + +void handle_insn_access_fault_code(void) { + volatile uint32_t mepc; + volatile mcause_t mcause = { 0 }; + volatile jvt_t jvt = { 0 }; + + // RWX !L & MODE OFF + volatile const uint32_t pmp_enable_access_all = 0x07070707; + + __asm__ volatile ( R"( + csrrs %[mc], mcause, x0 + csrrs %[mp], mepc, x0 + csrrs %[jvt], 0x017, x0 + )" + : [mc] "=r"(mcause.raw), + [mp] "=r"(mepc), + [jvt] "=r"(jvt.raw) + : + : + ); + + cvprintf(V_DEBUG, "In handler, mepc: 0x%08lx, mcause: 0x%08lx\n", mepc, mcause.raw); + + switch (mcause.clic.interrupt) { + case 0: + switch (mcause.clic.exccode) { + case 0x1: cvprintf(V_LOW, "Instruction access fault at 0x%08lx\n", mepc); + break; + case 0x2: cvprintf(V_LOW, "Invalid instruction fault at 0x%08lx\n", mepc); + break; + } + break; + case 1: + break; + } + + // check if address is locked, then unlock + // let test be responsible for cleaning up addr-regs to + // not clutter code here + if ( mcause.clic.exccode == 1 ) { + cvprintf(V_LOW, "Encountered read access fault, trying to enable pmp access\n"); + __asm__ volatile ( R"( + csrrw x0, pmpcfg0, %[access_ena] + csrrw x0, pmpcfg1, %[access_ena] + csrrw x0, pmpcfg2, %[access_ena] + csrrw x0, pmpcfg3, %[access_ena] + csrrw x0, pmpcfg4, %[access_ena] + csrrw x0, pmpcfg5, %[access_ena] + csrrw x0, pmpcfg6, %[access_ena] + csrrw x0, pmpcfg7, %[access_ena] + csrrw x0, pmpcfg8, %[access_ena] + csrrw x0, pmpcfg9, %[access_ena] + csrrw x0, pmpcfg10, %[access_ena] + csrrw x0, pmpcfg11, %[access_ena] + csrrw x0, pmpcfg12, %[access_ena] + csrrw x0, pmpcfg13, %[access_ena] + csrrw x0, pmpcfg14, %[access_ena] + csrrw x0, pmpcfg15, %[access_ena] + )" + : + : [access_ena] "r" (pmp_enable_access_all) + : + ); + } + + return; +} diff --git a/cv32e40s/tests/uvmt/base-tests/uvmt_cv32e40s_base_test_constants.sv b/cv32e40s/tests/uvmt/base-tests/uvmt_cv32e40s_base_test_constants.sv index 2feb828cc4..eb1ed3c90a 100644 --- a/cv32e40s/tests/uvmt/base-tests/uvmt_cv32e40s_base_test_constants.sv +++ b/cv32e40s/tests/uvmt/base-tests/uvmt_cv32e40s_base_test_constants.sv @@ -52,25 +52,27 @@ parameter CV_VP_REGISTER_BASE = 32'h0080_0000; parameter CV_VP_REGISTER_SIZE = 32'h0000_1000; - parameter CV_VP_VIRTUAL_PRINTER_OFFSET = 32'h0000_0000; - parameter CV_VP_RANDOM_NUM_OFFSET = 32'h0000_0040; - parameter CV_VP_CYCLE_COUNTER_OFFSET = 32'h0000_0080; - parameter CV_VP_STATUS_FLAGS_OFFSET = 32'h0000_00c0; - parameter CV_VP_FENCEI_TAMPER_OFFSET = 32'h0000_0100; - parameter CV_VP_INTR_TIMER_OFFSET = 32'h0000_0140; - parameter CV_VP_DEBUG_CONTROL_OFFSET = 32'h0000_0180; - parameter CV_VP_OBI_SLV_RESP_OFFSET = 32'h0000_01c0; - parameter CV_VP_SIG_WRITER_OFFSET = 32'h0000_0200; - - parameter CV_VP_VIRTUAL_PRINTER_BASE = CV_VP_REGISTER_BASE + CV_VP_VIRTUAL_PRINTER_OFFSET; - parameter CV_VP_RANDOM_NUM_BASE = CV_VP_REGISTER_BASE + CV_VP_RANDOM_NUM_OFFSET; - parameter CV_VP_CYCLE_COUNTER_BASE = CV_VP_REGISTER_BASE + CV_VP_CYCLE_COUNTER_OFFSET; - parameter CV_VP_STATUS_FLAGS_BASE = CV_VP_REGISTER_BASE + CV_VP_STATUS_FLAGS_OFFSET; - parameter CV_VP_INTR_TIMER_BASE = CV_VP_REGISTER_BASE + CV_VP_INTR_TIMER_OFFSET; - parameter CV_VP_DEBUG_CONTROL_BASE = CV_VP_REGISTER_BASE + CV_VP_DEBUG_CONTROL_OFFSET; - parameter CV_VP_OBI_SLV_RESP_BASE = CV_VP_REGISTER_BASE + CV_VP_OBI_SLV_RESP_OFFSET; - parameter CV_VP_SIG_WRITER_BASE = CV_VP_REGISTER_BASE + CV_VP_SIG_WRITER_OFFSET; - parameter CV_VP_FENCEI_TAMPER_BASE = CV_VP_REGISTER_BASE + CV_VP_FENCEI_TAMPER_OFFSET; + parameter CV_VP_VIRTUAL_PRINTER_OFFSET = 32'h0000_0000; + parameter CV_VP_RANDOM_NUM_OFFSET = 32'h0000_0040; + parameter CV_VP_STATUS_FLAGS_OFFSET = 32'h0000_00c0; + parameter CV_VP_CYCLE_COUNTER_OFFSET = 32'h0000_0080; + parameter CV_VP_FENCEI_TAMPER_OFFSET = 32'h0000_0100; + parameter CV_VP_INTR_TIMER_OFFSET = 32'h0000_0140; + parameter CV_VP_DEBUG_CONTROL_OFFSET = 32'h0000_0180; + parameter CV_VP_OBI_SLV_RESP_OFFSET = 32'h0000_01c0; + parameter CV_VP_SIG_WRITER_OFFSET = 32'h0000_0200; + parameter CV_VP_OBI_ERR_AWAIT_GOAHEAD_OFFSET = 32'h0000_0240; + + parameter CV_VP_CYCLE_COUNTER_BASE = CV_VP_REGISTER_BASE + CV_VP_CYCLE_COUNTER_OFFSET; + parameter CV_VP_DEBUG_CONTROL_BASE = CV_VP_REGISTER_BASE + CV_VP_DEBUG_CONTROL_OFFSET; + parameter CV_VP_FENCEI_TAMPER_BASE = CV_VP_REGISTER_BASE + CV_VP_FENCEI_TAMPER_OFFSET; + parameter CV_VP_INTR_TIMER_BASE = CV_VP_REGISTER_BASE + CV_VP_INTR_TIMER_OFFSET; + parameter CV_VP_OBI_ERR_AWAIT_GOAHEAD_BASE = CV_VP_REGISTER_BASE + CV_VP_OBI_ERR_AWAIT_GOAHEAD_OFFSET; + parameter CV_VP_OBI_SLV_RESP_BASE = CV_VP_REGISTER_BASE + CV_VP_OBI_SLV_RESP_OFFSET; + parameter CV_VP_RANDOM_NUM_BASE = CV_VP_REGISTER_BASE + CV_VP_RANDOM_NUM_OFFSET; + parameter CV_VP_SIG_WRITER_BASE = CV_VP_REGISTER_BASE + CV_VP_SIG_WRITER_OFFSET; + parameter CV_VP_STATUS_FLAGS_BASE = CV_VP_REGISTER_BASE + CV_VP_STATUS_FLAGS_OFFSET; + parameter CV_VP_VIRTUAL_PRINTER_BASE = CV_VP_REGISTER_BASE + CV_VP_VIRTUAL_PRINTER_OFFSET; `ifdef PARAM_SET_0 `include "cvverif_param_set_0.svh" diff --git a/lib/isa_decoder/isa_decoder.sv b/lib/isa_decoder/isa_decoder.sv index 1a0b0d593b..eb173dae71 100644 --- a/lib/isa_decoder/isa_decoder.sv +++ b/lib/isa_decoder/isa_decoder.sv @@ -136,6 +136,7 @@ function automatic gpr_t get_gpr_from_gpr_rvc(gpr_rvc_t gpr); gpr_t uncompressed_gpr; + casex (gpr.gpr) C_X8: uncompressed_gpr.gpr = X8; C_X9: uncompressed_gpr.gpr = X9; @@ -151,6 +152,24 @@ return uncompressed_gpr; endfunction : get_gpr_from_gpr_rvc + function automatic gpr_t get_gpr_from_gpr_rvc_sreg(gpr_rvc_sreg_t gpr); + gpr_t uncompressed_gpr; + + casex (gpr.gpr) + CS_X8: uncompressed_gpr.gpr = X8; + CS_X9: uncompressed_gpr.gpr = X9; + CS_X18: uncompressed_gpr.gpr = X18; + CS_X19: uncompressed_gpr.gpr = X19; + CS_X20: uncompressed_gpr.gpr = X20; + CS_X21: uncompressed_gpr.gpr = X21; + CS_X22: uncompressed_gpr.gpr = X22; + CS_X23: uncompressed_gpr.gpr = X23; + default: uncompressed_gpr.gpr = X0; // Function used wrong if we ever end up here + endcase + + return uncompressed_gpr; + endfunction : get_gpr_from_gpr_rvc_sreg + // --------------------------------------------------------------------------- // Find the value of immediate // --------------------------------------------------------------------------- @@ -311,463 +330,463 @@ casex (format) I_TYPE: begin if (asm.instr inside { FENCE_I, ECALL, EBREAK, MRET, DRET, WFI, WFE }) begin - asm.rd.valid = 0; - asm.rs1.valid = 0; - asm.rs2.valid = 0; - asm.imm.valid = 0; + asm.rd.valid = 0; + asm.rs1.valid = 0; + asm.rs2.valid = 0; + asm.imm.valid = 0; end else if (asm.instr inside { FENCE }) begin - asm.imm.imm_raw = instr.uncompressed.format.i.imm; - asm.imm.imm_raw_sorted = instr.uncompressed.format.i.imm; - asm.imm.imm_type = IMM; - asm.imm.width = 12; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_i(instr.uncompressed.format.i.imm); - asm.imm.valid = 1; + asm.imm.imm_raw = instr.uncompressed.format.i.imm; + asm.imm.imm_raw_sorted = instr.uncompressed.format.i.imm; + asm.imm.imm_type = IMM; + asm.imm.width = 12; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_i(instr.uncompressed.format.i.imm); + asm.imm.valid = 1; end else if (asm.instr inside { CSRRW, CSRRS, CSRRC }) begin - asm.rd.gpr = instr.uncompressed.format.i.rd.gpr; - asm.rs1.gpr = instr.uncompressed.format.i.rs1.gpr; - asm.csr.address = instr.uncompressed.format.i.imm; - asm.rd.valid = 1; - asm.rs1.valid = 1; - asm.csr.valid = 1; + asm.rd.gpr = instr.uncompressed.format.i.rd.gpr; + asm.rs1.gpr = instr.uncompressed.format.i.rs1.gpr; + asm.csr.address = instr.uncompressed.format.i.imm; + asm.rd.valid = 1; + asm.rs1.valid = 1; + asm.csr.valid = 1; end else if (asm.instr inside { CSRRWI, CSRRSI, CSRRCI }) begin - asm.rd.gpr = instr.uncompressed.format.i.rd.gpr; - asm.imm.imm_raw = instr.uncompressed.format.i.rs1; - asm.imm.imm_raw_sorted = instr.uncompressed.format.i.rs1; - asm.imm.imm_type = UIMM; - asm.imm.width = 5; - asm.imm.imm_value = instr.uncompressed.format.i.rs1; - asm.csr.address = instr.uncompressed.format.i.imm; - asm.rd.valid = 1; - asm.imm.valid = 1; - asm.csr.valid = 1; + asm.rd.gpr = instr.uncompressed.format.i.rd.gpr; + asm.imm.imm_raw = instr.uncompressed.format.i.rs1; + asm.imm.imm_raw_sorted = instr.uncompressed.format.i.rs1; + asm.imm.imm_type = UIMM; + asm.imm.width = 5; + asm.imm.imm_value = instr.uncompressed.format.i.rs1; + asm.csr.address = instr.uncompressed.format.i.imm; + asm.rd.valid = 1; + asm.imm.valid = 1; + asm.csr.valid = 1; end else if (asm.instr inside { RORI, BEXTI, BCLRI, BINVI, BSETI, SLLI, SRLI, SRAI }) begin - asm.rd.gpr = instr.uncompressed.format.i.rd.gpr; - asm.rs1.gpr = instr.uncompressed.format.i.rs1.gpr; - asm.imm.imm_raw = instr.uncompressed.format.i.imm.shamt; - asm.imm.imm_raw_sorted = instr.uncompressed.format.i.imm.shamt; - asm.imm.imm_type = SHAMT; - asm.imm.width = 5; - asm.imm.imm_value = instr.uncompressed.format.i.imm.shamt; - asm.rd.valid = 1; - asm.rs1.valid = 1; - asm.imm.valid = 1; + asm.rd.gpr = instr.uncompressed.format.i.rd.gpr; + asm.rs1.gpr = instr.uncompressed.format.i.rs1.gpr; + asm.imm.imm_raw = instr.uncompressed.format.i.imm.shamt; + asm.imm.imm_raw_sorted = instr.uncompressed.format.i.imm.shamt; + asm.imm.imm_type = SHAMT; + asm.imm.width = 5; + asm.imm.imm_value = instr.uncompressed.format.i.imm.shamt; + asm.rd.valid = 1; + asm.rs1.valid = 1; + asm.imm.valid = 1; end else begin - asm.rd.gpr = instr.uncompressed.format.i.rd.gpr; - asm.rs1.gpr = instr.uncompressed.format.i.rs1.gpr; - asm.imm.imm_raw = instr.uncompressed.format.i.imm; - asm.imm.imm_raw_sorted = instr.uncompressed.format.i.imm; - asm.imm.imm_type = IMM; - asm.imm.width = 12; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_i(instr.uncompressed.format.i.imm); - asm.rd.valid = 1; - asm.rs1.valid = 1; - asm.imm.valid = 1; + asm.rd.gpr = instr.uncompressed.format.i.rd.gpr; + asm.rs1.gpr = instr.uncompressed.format.i.rs1.gpr; + asm.imm.imm_raw = instr.uncompressed.format.i.imm; + asm.imm.imm_raw_sorted = instr.uncompressed.format.i.imm; + asm.imm.imm_type = IMM; + asm.imm.width = 12; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_i(instr.uncompressed.format.i.imm); + asm.rd.valid = 1; + asm.rs1.valid = 1; + asm.imm.valid = 1; end end J_TYPE: begin - asm.rd.gpr = instr.uncompressed.format.j.rd.gpr; - asm.imm.imm_raw = instr.uncompressed.format.j.imm; - asm.imm.imm_raw_sorted = get_sort_j_imm(instr); - asm.imm.imm_type = OFFSET; - asm.imm.width = 20; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_j(get_sort_j_imm(instr)); - asm.rd.valid = 1; - asm.imm.valid = 1; + asm.rd.gpr = instr.uncompressed.format.j.rd.gpr; + asm.imm.imm_raw = instr.uncompressed.format.j.imm; + asm.imm.imm_raw_sorted = get_sort_j_imm(instr); + asm.imm.imm_type = OFFSET; + asm.imm.width = 20; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_j(get_sort_j_imm(instr)); + asm.rd.valid = 1; + asm.imm.valid = 1; end S_TYPE: begin - asm.rs1.gpr = instr.uncompressed.format.s.rs1.gpr; - asm.rs2.gpr = instr.uncompressed.format.s.rs2.gpr; - asm.imm.imm_raw = get_sort_s_imm(instr); - asm.imm.imm_raw_sorted = get_sort_s_imm(instr); - asm.imm.imm_type = IMM; - asm.imm.width = 12; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_i(get_sort_s_imm(instr)); - asm.rs1.valid = 1; - asm.rs2.valid = 1; - asm.imm.valid = 1; + asm.rs1.gpr = instr.uncompressed.format.s.rs1.gpr; + asm.rs2.gpr = instr.uncompressed.format.s.rs2.gpr; + asm.imm.imm_raw = get_sort_s_imm(instr); + asm.imm.imm_raw_sorted = get_sort_s_imm(instr); + asm.imm.imm_type = IMM; + asm.imm.width = 12; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_i(get_sort_s_imm(instr)); + asm.rs1.valid = 1; + asm.rs2.valid = 1; + asm.imm.valid = 1; end R_TYPE: begin if ( asm.instr inside { LR_W, SC_W, AMOSWAP_W, AMOADD_W, AMOXOR_W, AMOAND_W, AMOOR_W, AMOMIN_W, AMOMAX_W, AMOMINU_W, AMOMAXU_W } ) begin - asm.rd.gpr = instr.uncompressed.format.r.rd.gpr; - asm.rs1.gpr = instr.uncompressed.format.r.rs1.gpr; - asm.rs2.gpr = instr.uncompressed.format.r.rs2.gpr; - asm.atomic.aq = instr.uncompressed.format.r.funct7[26]; - asm.atomic.rl = instr.uncompressed.format.r.funct7[25]; - asm.rd.valid = 1; - asm.rs1.valid = 1; - asm.rs2.valid = 1; - asm.atomic.valid = 1; + asm.rd.gpr = instr.uncompressed.format.r.rd.gpr; + asm.rs1.gpr = instr.uncompressed.format.r.rs1.gpr; + asm.rs2.gpr = instr.uncompressed.format.r.rs2.gpr; + asm.atomic.aq = instr.uncompressed.format.r.funct7[26]; + asm.atomic.rl = instr.uncompressed.format.r.funct7[25]; + asm.rd.valid = 1; + asm.rs1.valid = 1; + asm.rs2.valid = 1; + asm.atomic.valid = 1; end else begin - asm.rd.gpr = instr.uncompressed.format.r.rd.gpr; - asm.rs1.gpr = instr.uncompressed.format.r.rs1.gpr; - asm.rs2.gpr = instr.uncompressed.format.r.rs2.gpr; - asm.rd.valid = 1; - asm.rs1.valid = 1; - asm.rs2.valid = 1; + asm.rd.gpr = instr.uncompressed.format.r.rd.gpr; + asm.rs1.gpr = instr.uncompressed.format.r.rs1.gpr; + asm.rs2.gpr = instr.uncompressed.format.r.rs2.gpr; + asm.rd.valid = 1; + asm.rs1.valid = 1; + asm.rs2.valid = 1; end end R4_TYPE: begin - asm.rd.gpr = instr.uncompressed.format.r4.rd.gpr; - asm.rs1.gpr = instr.uncompressed.format.r4.rs1.gpr; - asm.rs2.gpr = instr.uncompressed.format.r4.rs2.gpr; - asm.rs3.gpr = instr.uncompressed.format.r4.rs3.gpr; - asm.rd.valid = 1; - asm.rs1.valid = 1; - asm.rs2.valid = 1; - asm.rs3.valid = 1; + asm.rd.gpr = instr.uncompressed.format.r4.rd.gpr; + asm.rs1.gpr = instr.uncompressed.format.r4.rs1.gpr; + asm.rs2.gpr = instr.uncompressed.format.r4.rs2.gpr; + asm.rs3.gpr = instr.uncompressed.format.r4.rs3.gpr; + asm.rd.valid = 1; + asm.rs1.valid = 1; + asm.rs2.valid = 1; + asm.rs3.valid = 1; end B_TYPE: begin - asm.rs1.gpr = instr.uncompressed.format.b.rs1.gpr; - asm.rs2.gpr = instr.uncompressed.format.b.rs2.gpr; - asm.imm.imm_raw = {instr.uncompressed.format.b.imm_h, instr.uncompressed.format.b.imm_l}; - asm.imm.imm_raw_sorted = get_sort_b_imm(instr); - asm.imm.imm_type = IMM; - asm.imm.width = 12; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_b(get_sort_b_imm(instr)); - asm.rs1.valid = 1; - asm.rs2.valid = 1; - asm.imm.valid = 1; + asm.rs1.gpr = instr.uncompressed.format.b.rs1.gpr; + asm.rs2.gpr = instr.uncompressed.format.b.rs2.gpr; + asm.imm.imm_raw = {instr.uncompressed.format.b.imm_h, instr.uncompressed.format.b.imm_l}; + asm.imm.imm_raw_sorted = get_sort_b_imm(instr); + asm.imm.imm_type = IMM; + asm.imm.width = 12; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_b(get_sort_b_imm(instr)); + asm.rs1.valid = 1; + asm.rs2.valid = 1; + asm.imm.valid = 1; end U_TYPE: begin - asm.rd.gpr = instr.uncompressed.format.u.rd.gpr; - asm.imm.imm_raw = instr.uncompressed.format.u.imm; - asm.imm.imm_raw_sorted = instr.uncompressed.format.u.imm; - asm.imm.imm_type = IMM; - asm.imm.width = 20; - asm.imm.imm_value = { instr.uncompressed.format.u.imm, 12'b0000_0000_0000 }; - asm.rd.valid = 1; - asm.imm.valid = 1; + asm.rd.gpr = instr.uncompressed.format.u.rd.gpr; + asm.imm.imm_raw = instr.uncompressed.format.u.imm; + asm.imm.imm_raw_sorted = instr.uncompressed.format.u.imm; + asm.imm.imm_type = IMM; + asm.imm.width = 20; + asm.imm.imm_value = { instr.uncompressed.format.u.imm, 12'b0000_0000_0000 }; + asm.rd.valid = 1; + asm.imm.valid = 1; end // Compressed CR_TYPE: begin if (name inside { C_EBREAK }) begin - asm.rd.valid = 0; - asm.rs1.valid = 0; - asm.rs2.valid = 0; - asm.rs3.valid = 0; - asm.imm.valid = 0; + asm.rd.valid = 0; + asm.rs1.valid = 0; + asm.rs2.valid = 0; + asm.rs3.valid = 0; + asm.imm.valid = 0; end else if (name inside { C_MV }) begin - asm.rd.gpr = instr.compressed.format.cr.rd_rs1.gpr; - asm.rs1.gpr = instr.compressed.format.cr.rd_rs1.gpr; - asm.rs2.gpr = instr.compressed.format.cr.rs2.gpr; - asm.rd.valid = 1; - asm.rs2.valid = 1; - asm.rs1.valid = 1; + asm.rd.gpr = instr.compressed.format.cr.rd_rs1.gpr; + asm.rs1.gpr = instr.compressed.format.cr.rd_rs1.gpr; + asm.rs2.gpr = instr.compressed.format.cr.rs2.gpr; + asm.rd.valid = 1; + asm.rs2.valid = 1; + asm.rs1.valid = 1; end else if (name inside { C_ADD }) begin - asm.rd.gpr = instr.compressed.format.cr.rd_rs1.gpr; - asm.rs1.gpr = instr.compressed.format.cr.rd_rs1.gpr; - asm.rs2.gpr = instr.compressed.format.cr.rs2.gpr; - asm.rd.valid = 1; - asm.rs1.valid = 1; - asm.rs2.valid = 1; + asm.rd.gpr = instr.compressed.format.cr.rd_rs1.gpr; + asm.rs1.gpr = instr.compressed.format.cr.rd_rs1.gpr; + asm.rs2.gpr = instr.compressed.format.cr.rs2.gpr; + asm.rd.valid = 1; + asm.rs1.valid = 1; + asm.rs2.valid = 1; end else if (name inside { C_JR, C_JALR }) begin - asm.rs1.gpr = instr.compressed.format.cr.rd_rs1.gpr; - asm.rs2.gpr = instr.compressed.format.cr.rs2.gpr; - asm.rs1.valid = 1; - asm.rs2.valid = 1; + asm.rs1.gpr = instr.compressed.format.cr.rd_rs1.gpr; + asm.rs2.gpr = instr.compressed.format.cr.rs2.gpr; + asm.rs1.valid = 1; + asm.rs2.valid = 1; end end CI_TYPE: begin if (name inside { C_NOP, C_ADDI }) begin - asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; - asm.rs1.gpr = instr.compressed.format.ci.rd_rs1.gpr; - asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; - asm.imm.imm_raw_sorted = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; - asm.imm.imm_type = IMM; - asm.imm.width = 6; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_ci({ instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }); - asm.rd.valid = 1; - asm.rs1.valid = 1; - asm.imm.valid = 1; - end else if (name == C_LI) begin - asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; - asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; - asm.imm.imm_raw_sorted = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; - asm.imm.imm_type = IMM; - asm.imm.width = 6; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_ci({ instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }); - asm.rd.valid = 1; - asm.imm.valid = 1; - end else if (name == C_LUI) begin - asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; - asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; - asm.imm.imm_raw_sorted = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; - asm.imm.imm_type = NZIMM; - asm.imm.width = 6; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_ci_lui({ instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }); - asm.rd.valid = 1; - asm.imm.valid = 1; + asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; + asm.rs1.gpr = instr.compressed.format.ci.rd_rs1.gpr; + asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; + asm.imm.imm_raw_sorted = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; + asm.imm.imm_type = IMM; + asm.imm.width = 6; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_ci({ instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }); + asm.rd.valid = 1; + asm.rs1.valid = 1; + asm.imm.valid = 1; + end else if (name == C_LI) begin + asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; + asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; + asm.imm.imm_raw_sorted = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; + asm.imm.imm_type = IMM; + asm.imm.width = 6; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_ci({ instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }); + asm.rd.valid = 1; + asm.imm.valid = 1; + end else if (name == C_LUI) begin + asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; + asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; + asm.imm.imm_raw_sorted = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; + asm.imm.imm_type = NZIMM; + asm.imm.width = 6; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_ci_lui({ instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }); + asm.rd.valid = 1; + asm.imm.valid = 1; end else if (name inside { C_LWSP }) begin - asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; - asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; - asm.imm.imm_raw_sorted = get_sort_ci_imm_lwsp(instr); - asm.imm.imm_type = OFFSET; - asm.imm.width = 6; - asm.imm.imm_value = {24'b0, get_sort_ci_imm_lwsp(instr), 2'b0}; - asm.rd.valid = 1; - asm.imm.valid = 1; + asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; + asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; + asm.imm.imm_raw_sorted = get_sort_ci_imm_lwsp(instr); + asm.imm.imm_type = OFFSET; + asm.imm.width = 6; + asm.imm.imm_value = {24'b0, get_sort_ci_imm_lwsp(instr), 2'b0}; + asm.rd.valid = 1; + asm.imm.valid = 1; end else if (name inside { C_ADDI16SP }) begin - asm.rs1.gpr = instr.compressed.format.ci.rd_rs1.gpr; - asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; - asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; - asm.imm.imm_raw_sorted = get_sort_ci_imm_addi16sp(instr); - asm.imm.imm_type = NZIMM; - asm.imm.width = 6; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_ci_addi16sp(get_sort_ci_imm_addi16sp(instr)); - asm.rs1.valid = 1; - asm.rd.valid = 1; - asm.imm.valid = 1; + asm.rs1.gpr = instr.compressed.format.ci.rd_rs1.gpr; + asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; + asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; + asm.imm.imm_raw_sorted = get_sort_ci_imm_addi16sp(instr); + asm.imm.imm_type = NZIMM; + asm.imm.width = 6; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_ci_addi16sp(get_sort_ci_imm_addi16sp(instr)); + asm.rs1.valid = 1; + asm.rd.valid = 1; + asm.imm.valid = 1; end else if (name inside { C_SLLI }) begin - asm.rs1.gpr = instr.compressed.format.ci.rd_rs1.gpr; - asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; - asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; - asm.imm.imm_raw_sorted = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; - asm.imm.imm_type = SHAMT; - asm.imm.width = 6; - asm.imm.imm_value = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; - asm.rs1.valid = 1; - asm.rd.valid = 1; - asm.imm.valid = 1; + asm.rs1.gpr = instr.compressed.format.ci.rd_rs1.gpr; + asm.rd.gpr = instr.compressed.format.ci.rd_rs1.gpr; + asm.imm.imm_raw = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; + asm.imm.imm_raw_sorted = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; + asm.imm.imm_type = SHAMT; + asm.imm.width = 6; + asm.imm.imm_value = { instr.compressed.format.ci.imm_12, instr.compressed.format.ci.imm_6_2 }; + asm.rs1.valid = 1; + asm.rd.valid = 1; + asm.imm.valid = 1; end end CSS_TYPE: begin - asm.rs2.gpr = instr.compressed.format.css.rs2.gpr; - asm.imm.imm_raw = instr.compressed.format.css.imm; - asm.imm.imm_raw_sorted = { instr.compressed.format.css.imm[9:7], instr.compressed.format.css.imm[12:10] }; - asm.imm.imm_type = OFFSET; - asm.imm.width = 6; - asm.imm.imm_value = { 24'b0, instr.compressed.format.css.imm[9:7], instr.compressed.format.css.imm[12:10], 2'b0 }; - asm.rs2.valid = 1; - asm.imm.valid = 1; + asm.rs2.gpr = instr.compressed.format.css.rs2.gpr; + asm.imm.imm_raw = instr.compressed.format.css.imm; + asm.imm.imm_raw_sorted = { instr.compressed.format.css.imm[9:7], instr.compressed.format.css.imm[12:10] }; + asm.imm.imm_type = OFFSET; + asm.imm.width = 6; + asm.imm.imm_value = { 24'b0, instr.compressed.format.css.imm[9:7], instr.compressed.format.css.imm[12:10], 2'b0 }; + asm.rs2.valid = 1; + asm.imm.valid = 1; end CIW_TYPE: begin - asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.ciw.rd.gpr); - asm.rd.gpr_rvc = instr.compressed.format.ciw.rd.gpr; - asm.imm.imm_raw = instr.compressed.format.ciw.imm; - asm.imm.imm_raw_sorted = get_sort_ciw_imm(instr); - asm.imm.imm_type = NZUIMM; - asm.imm.width = 8; - asm.imm.imm_value = { 22'b0, get_sort_ciw_imm(instr), 2'b0 }; - asm.imm.valid = 1; - asm.rd.valid = 1; - asm.rd.valid_gpr_rvc = 1; + asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.ciw.rd.gpr); + asm.rd.gpr_rvc = instr.compressed.format.ciw.rd.gpr; + asm.imm.imm_raw = instr.compressed.format.ciw.imm; + asm.imm.imm_raw_sorted = get_sort_ciw_imm(instr); + asm.imm.imm_type = NZUIMM; + asm.imm.width = 8; + asm.imm.imm_value = { 22'b0, get_sort_ciw_imm(instr), 2'b0 }; + asm.imm.valid = 1; + asm.rd.valid = 1; + asm.rd.valid_gpr_rvc = 1; end CL_TYPE: begin - asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cl.rd.gpr); - asm.rd.gpr_rvc = instr.compressed.format.cl.rd.gpr; - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cl.rs1.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.cl.rs1.gpr; - asm.imm.imm_raw = { instr.compressed.format.cl.imm_12_10, instr.compressed.format.cl.imm_6_5 }; - asm.imm.imm_raw_sorted = get_sort_cl_imm(instr); - asm.imm.imm_type = OFFSET; - asm.imm.width = 5; - asm.imm.imm_value = { 25'b0, get_sort_cl_imm(instr), 2'b0 }; - asm.rd.valid = 1; - asm.rd.valid_gpr_rvc = 1; - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.imm.valid = 1; + asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cl.rd.gpr); + asm.rd.gpr_rvc = instr.compressed.format.cl.rd.gpr; + asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cl.rs1.gpr); + asm.rs1.gpr_rvc = instr.compressed.format.cl.rs1.gpr; + asm.imm.imm_raw = { instr.compressed.format.cl.imm_12_10, instr.compressed.format.cl.imm_6_5 }; + asm.imm.imm_raw_sorted = get_sort_cl_imm(instr); + asm.imm.imm_type = OFFSET; + asm.imm.width = 5; + asm.imm.imm_value = { 25'b0, get_sort_cl_imm(instr), 2'b0 }; + asm.rd.valid = 1; + asm.rd.valid_gpr_rvc = 1; + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc = 1; + asm.imm.valid = 1; end CS_TYPE: begin - asm.rs2.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cs.rs2.gpr); - asm.rs2.gpr_rvc = instr.compressed.format.cs.rs2.gpr; - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cs.rs1.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.cs.rs1.gpr; - asm.imm.imm_raw = { instr.compressed.format.cs.imm_12_10, instr.compressed.format.cs.imm_6_5 }; - asm.imm.imm_raw_sorted = get_sort_cs_imm(instr); - asm.imm.imm_type = OFFSET; - asm.imm.width = 5; - asm.imm.imm_value = { 25'b0, get_sort_cs_imm(instr), 2'b0 }; - asm.rs2.valid = 1; - asm.rs2.valid_gpr_rvc = 1; - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.imm.valid = 1; + asm.rs2.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cs.rs2.gpr); + asm.rs2.gpr_rvc = instr.compressed.format.cs.rs2.gpr; + asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cs.rs1.gpr); + asm.rs1.gpr_rvc = instr.compressed.format.cs.rs1.gpr; + asm.imm.imm_raw = { instr.compressed.format.cs.imm_12_10, instr.compressed.format.cs.imm_6_5 }; + asm.imm.imm_raw_sorted = get_sort_cs_imm(instr); + asm.imm.imm_type = OFFSET; + asm.imm.width = 5; + asm.imm.imm_value = { 25'b0, get_sort_cs_imm(instr), 2'b0 }; + asm.rs2.valid = 1; + asm.rs2.valid_gpr_rvc = 1; + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc = 1; + asm.imm.valid = 1; end CA_TYPE: begin - asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.ca.rd_rs1.gpr); - asm.rd.gpr_rvc = instr.compressed.format.ca.rd_rs1.gpr; - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.ca.rd_rs1.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.ca.rd_rs1.gpr; - asm.rs2.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.ca.rs2.gpr); - asm.rs2.gpr_rvc = instr.compressed.format.ca.rs2.gpr; - asm.rd.valid = 1; - asm.rd.valid_gpr_rvc = 1; - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.rs2.valid = 1; - asm.rs2.valid_gpr_rvc = 1; + asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.ca.rd_rs1.gpr); + asm.rd.gpr_rvc = instr.compressed.format.ca.rd_rs1.gpr; + asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.ca.rd_rs1.gpr); + asm.rs1.gpr_rvc = instr.compressed.format.ca.rd_rs1.gpr; + asm.rs2.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.ca.rs2.gpr); + asm.rs2.gpr_rvc = instr.compressed.format.ca.rs2.gpr; + asm.rd.valid = 1; + asm.rd.valid_gpr_rvc = 1; + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc = 1; + asm.rs2.valid = 1; + asm.rs2.valid_gpr_rvc = 1; end CB_TYPE: begin if (name inside { C_SRLI, C_SRAI }) begin - asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cb.rd_rs1.gpr); - asm.rd.gpr_rvc = instr.compressed.format.cb.rd_rs1.gpr; - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cb.rd_rs1.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.cb.rd_rs1.gpr; - asm.imm.imm_raw = { instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }; - asm.imm.imm_raw_sorted = { instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }; - asm.imm.imm_type = SHAMT; - asm.imm.width = 6; - asm.imm.imm_value = { instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }; - asm.rd.valid = 1; - asm.rd.valid_gpr_rvc = 1; - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.imm.valid = 1; + asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cb.rd_rs1.gpr); + asm.rd.gpr_rvc = instr.compressed.format.cb.rd_rs1.gpr; + asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cb.rd_rs1.gpr); + asm.rs1.gpr_rvc = instr.compressed.format.cb.rd_rs1.gpr; + asm.imm.imm_raw = { instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }; + asm.imm.imm_raw_sorted = { instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }; + asm.imm.imm_type = SHAMT; + asm.imm.width = 6; + asm.imm.imm_value = { instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }; + asm.rd.valid = 1; + asm.rd.valid_gpr_rvc = 1; + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc = 1; + asm.imm.valid = 1; end else if (name inside { C_BEQZ, C_BNEZ }) begin - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cb.rd_rs1.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.cb.rd_rs1.gpr; - asm.imm.imm_raw = { instr.compressed.format.cb.offset_12_10, instr.compressed.format.cb.offset_6_2 }; - asm.imm.imm_raw_sorted = get_sort_cb_imm_not_sequential(instr); - asm.imm.imm_type = OFFSET; - asm.imm.width = 8; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_cb(get_sort_cb_imm_not_sequential(instr)); - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.imm.valid = 1; + asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cb.rd_rs1.gpr); + asm.rs1.gpr_rvc = instr.compressed.format.cb.rd_rs1.gpr; + asm.imm.imm_raw = { instr.compressed.format.cb.offset_12_10, instr.compressed.format.cb.offset_6_2 }; + asm.imm.imm_raw_sorted = get_sort_cb_imm_not_sequential(instr); + asm.imm.imm_type = OFFSET; + asm.imm.width = 8; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_cb(get_sort_cb_imm_not_sequential(instr)); + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc = 1; + asm.imm.valid = 1; end else if (name inside { C_ANDI }) begin - asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cb.rd_rs1.gpr); - asm.rd.gpr_rvc = instr.compressed.format.cb.rd_rs1.gpr; - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cb.rd_rs1.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.cb.rd_rs1.gpr; - asm.imm.imm_raw = { instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }; - asm.imm.imm_raw_sorted = { instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }; - asm.imm.imm_type = IMM; - asm.imm.width = 6; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_cb({ instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }); - asm.rd.valid = 1; - asm.rd.valid_gpr_rvc = 1; - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.imm.valid = 1; + asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cb.rd_rs1.gpr); + asm.rd.gpr_rvc = instr.compressed.format.cb.rd_rs1.gpr; + asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cb.rd_rs1.gpr); + asm.rs1.gpr_rvc = instr.compressed.format.cb.rd_rs1.gpr; + asm.imm.imm_raw = { instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }; + asm.imm.imm_raw_sorted = { instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }; + asm.imm.imm_type = IMM; + asm.imm.width = 6; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_cb({ instr.compressed.format.cb.offset_12_10[12], instr.compressed.format.cb.offset_6_2 }); + asm.rd.valid = 1; + asm.rd.valid_gpr_rvc = 1; + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc = 1; + asm.imm.valid = 1; end end CJ_TYPE: begin - asm.imm.imm_raw = instr.compressed.format.cj.imm; - asm.imm.imm_raw_sorted = get_sort_cj_imm(instr); - asm.imm.imm_type = OFFSET; - asm.imm.width = 11; - asm.imm.sign_ext = 1; - asm.imm.imm_value = get_imm_value_cj(get_sort_cj_imm(instr)); - asm.imm.valid = 1; + asm.imm.imm_raw = instr.compressed.format.cj.imm; + asm.imm.imm_raw_sorted = get_sort_cj_imm(instr); + asm.imm.imm_type = OFFSET; + asm.imm.width = 11; + asm.imm.sign_ext = 1; + asm.imm.imm_value = get_imm_value_cj(get_sort_cj_imm(instr)); + asm.imm.valid = 1; end CLB_TYPE: begin - asm.imm.imm_raw = instr.compressed.format.clb.uimm; - asm.imm.imm_raw_sorted = { instr.compressed.format.clb.uimm[5], instr.compressed.format.clb.uimm[6] }; - asm.imm.imm_type = UIMM; - asm.imm.width = 2; - asm.imm.imm_value = { instr.compressed.format.clb.uimm[5], instr.compressed.format.clb.uimm[6] }; - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.clb.rs1.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.clb.rs1.gpr; - asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.clb.rd.gpr); - asm.rd.gpr_rvc = instr.compressed.format.clb.rd.gpr; - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.rd.valid = 1; - asm.rd.valid_gpr_rvc = 1; - asm.imm.valid = 1; + asm.imm.imm_raw = instr.compressed.format.clb.uimm; + asm.imm.imm_raw_sorted = { instr.compressed.format.clb.uimm[5], instr.compressed.format.clb.uimm[6] }; + asm.imm.imm_type = UIMM; + asm.imm.width = 2; + asm.imm.imm_value = { instr.compressed.format.clb.uimm[5], instr.compressed.format.clb.uimm[6] }; + asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.clb.rs1.gpr); + asm.rs1.gpr_rvc = instr.compressed.format.clb.rs1.gpr; + asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.clb.rd.gpr); + asm.rd.gpr_rvc = instr.compressed.format.clb.rd.gpr; + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc = 1; + asm.rd.valid = 1; + asm.rd.valid_gpr_rvc = 1; + asm.imm.valid = 1; end CSB_TYPE: begin - asm.imm.imm_raw = instr.compressed.format.csb.uimm; - asm.imm.imm_raw_sorted = { instr.compressed.format.csb.uimm[5], instr.compressed.format.csb.uimm[6] }; - asm.imm.imm_type = UIMM; - asm.imm.width = 2; - asm.imm.imm_value = { instr.compressed.format.csb.uimm[5], instr.compressed.format.csb.uimm[6] }; - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.csb.rs1.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.csb.rs1.gpr; - asm.rs2.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.csb.rs2.gpr); - asm.rs2.gpr_rvc = instr.compressed.format.csb.rs2.gpr; - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.rs2.valid = 1; - asm.rs2.valid_gpr_rvc = 1; - asm.imm.valid = 1; + asm.imm.imm_raw = instr.compressed.format.csb.uimm; + asm.imm.imm_raw_sorted = { instr.compressed.format.csb.uimm[5], instr.compressed.format.csb.uimm[6] }; + asm.imm.imm_type = UIMM; + asm.imm.width = 2; + asm.imm.imm_value = { instr.compressed.format.csb.uimm[5], instr.compressed.format.csb.uimm[6] }; + asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.csb.rs1.gpr); + asm.rs1.gpr_rvc = instr.compressed.format.csb.rs1.gpr; + asm.rs2.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.csb.rs2.gpr); + asm.rs2.gpr_rvc = instr.compressed.format.csb.rs2.gpr; + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc = 1; + asm.rs2.valid = 1; + asm.rs2.valid_gpr_rvc = 1; + asm.imm.valid = 1; end CLH_TYPE: begin - asm.imm.imm_raw = instr.compressed.format.clh.uimm; - asm.imm.imm_raw_sorted = instr.compressed.format.clh.uimm; - asm.imm.imm_type = UIMM; - asm.imm.width = 1; - asm.imm.imm_value = { 30'b0, instr.compressed.format.clh.uimm }; - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.clh.rs1.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.clh.rs1.gpr; - asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.clh.rd.gpr); - asm.rd.gpr_rvc = instr.compressed.format.clh.rd.gpr; - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.rd.valid = 1; - asm.rd.valid_gpr_rvc = 1; - asm.imm.valid = 1; + asm.imm.imm_raw = instr.compressed.format.clh.uimm; + asm.imm.imm_raw_sorted = instr.compressed.format.clh.uimm; + asm.imm.imm_type = UIMM; + asm.imm.width = 1; + asm.imm.imm_value = { 30'b0, instr.compressed.format.clh.uimm }; + asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.clh.rs1.gpr); + asm.rs1.gpr_rvc = instr.compressed.format.clh.rs1.gpr; + asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.clh.rd.gpr); + asm.rd.gpr_rvc = instr.compressed.format.clh.rd.gpr; + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc = 1; + asm.rd.valid = 1; + asm.rd.valid_gpr_rvc = 1; + asm.imm.valid = 1; end CSH_TYPE: begin - asm.imm.imm_raw = instr.compressed.format.csh.uimm; - asm.imm.imm_raw_sorted = instr.compressed.format.csh.uimm; - asm.imm.imm_type = UIMM; - asm.imm.width = 1; - asm.imm.imm_value = {30'b0, instr.compressed.format.csh.uimm, 1'b0}; - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.csh.rs1.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.csh.rs1.gpr; - asm.rs2.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.csh.rs2.gpr); - asm.rs2.gpr_rvc = instr.compressed.format.csh.rs2.gpr; - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.rs2.valid = 1; - asm.rs2.valid_gpr_rvc = 1; - asm.imm.valid = 1; + asm.imm.imm_raw = instr.compressed.format.csh.uimm; + asm.imm.imm_raw_sorted = instr.compressed.format.csh.uimm; + asm.imm.imm_type = UIMM; + asm.imm.width = 1; + asm.imm.imm_value = {30'b0, instr.compressed.format.csh.uimm, 1'b0}; + asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.csh.rs1.gpr); + asm.rs1.gpr_rvc = instr.compressed.format.csh.rs1.gpr; + asm.rs2.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.csh.rs2.gpr); + asm.rs2.gpr_rvc = instr.compressed.format.csh.rs2.gpr; + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc = 1; + asm.rs2.valid = 1; + asm.rs2.valid_gpr_rvc = 1; + asm.imm.valid = 1; end CU_TYPE: begin - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cu.rd_rs1.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.cu.rd_rs1.gpr; - asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cu.rd_rs1.gpr); - asm.rd.gpr_rvc = instr.compressed.format.cu.rd_rs1.gpr; - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.rd.valid = 1; - asm.rd.valid_gpr_rvc = 1; + asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cu.rd_rs1.gpr); + asm.rs1.gpr_rvc = instr.compressed.format.cu.rd_rs1.gpr; + asm.rd.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cu.rd_rs1.gpr); + asm.rd.gpr_rvc = instr.compressed.format.cu.rd_rs1.gpr; + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc = 1; + asm.rd.valid = 1; + asm.rd.valid_gpr_rvc = 1; end CMMV_TYPE: begin - asm.rs1.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cmmv.r1s.gpr); - asm.rs1.gpr_rvc = instr.compressed.format.cmmv.r1s.gpr; - asm.rs2.gpr = get_gpr_from_gpr_rvc(instr.compressed.format.cmmv.r2s.gpr); - asm.rs2.gpr_rvc = instr.compressed.format.cmmv.r2s.gpr; - asm.rs1.valid = 1; - asm.rs1.valid_gpr_rvc = 1; - asm.rs2.valid = 1; - asm.rs2.valid_gpr_rvc = 1; + asm.rs1.gpr = get_gpr_from_gpr_rvc_sreg(instr.compressed.format.cmmv.r1s.gpr); + asm.rs1.gpr_rvc_sreg = instr.compressed.format.cmmv.r1s.gpr; + asm.rs2.gpr = get_gpr_from_gpr_rvc_sreg(instr.compressed.format.cmmv.r2s.gpr); + asm.rs2.gpr_rvc_sreg = instr.compressed.format.cmmv.r2s.gpr; + asm.rs1.valid = 1; + asm.rs1.valid_gpr_rvc_sreg = 1; + asm.rs2.valid = 1; + asm.rs2.valid_gpr_rvc_sreg = 1; end CMJT_TYPE: begin - asm.imm.imm_raw = instr.compressed.format.cmjt.index; - asm.imm.imm_raw_sorted = instr.compressed.format.cmjt.index; - asm.imm.imm_type = INDEX; - asm.imm.width = 1; - asm.imm.imm_value = instr.compressed.format.cmjt.index; - asm.imm.valid = 1; + asm.imm.imm_raw = instr.compressed.format.cmjt.index; + asm.imm.imm_raw_sorted = instr.compressed.format.cmjt.index; + asm.imm.imm_type = INDEX; + asm.imm.width = 1; + asm.imm.imm_value = instr.compressed.format.cmjt.index; + asm.imm.valid = 1; end CMPP_TYPE: begin - asm.imm.imm_raw = instr.compressed.format.cmpp.spimm; - asm.imm.imm_raw_sorted = instr.compressed.format.cmpp.spimm; - asm.imm.imm_type = SPIMM; - asm.imm.width = 1; - asm.rlist.rlist = instr.compressed.format.cmpp.urlist; - asm.stack_adj.stack_adj = get_stack_adj(instr.compressed.format.cmpp.urlist, instr.compressed.format.cmpp.spimm); - asm.imm.valid = 1; - asm.rs1.gpr = instr.compressed.format.csh.rs1.gpr; - asm.rs2.gpr = instr.compressed.format.csh.rs2.gpr; - asm.rs1.valid = 1; - asm.rs2.valid = 1; - asm.rlist.valid = 1; - asm.stack_adj.valid = 1; + asm.imm.imm_raw = instr.compressed.format.cmpp.spimm; + asm.imm.imm_raw_sorted = instr.compressed.format.cmpp.spimm; + asm.imm.imm_type = SPIMM; + asm.imm.width = 1; + asm.rlist.rlist = instr.compressed.format.cmpp.urlist; + asm.stack_adj.stack_adj = get_stack_adj(instr.compressed.format.cmpp.urlist, instr.compressed.format.cmpp.spimm); + asm.imm.valid = 1; + asm.rs1.gpr = instr.compressed.format.csh.rs1.gpr; + asm.rs2.gpr = instr.compressed.format.csh.rs2.gpr; + asm.rs1.valid = 1; + asm.rs2.valid = 1; + asm.rlist.valid = 1; + asm.stack_adj.valid = 1; end default : ; diff --git a/lib/isa_decoder/isa_typedefs.sv b/lib/isa_decoder/isa_typedefs.sv index 374985c103..416e705db9 100644 --- a/lib/isa_decoder/isa_typedefs.sv +++ b/lib/isa_decoder/isa_typedefs.sv @@ -295,12 +295,40 @@ C_A5 = 3'b111 } gpr_rvc_abi_name_e; + typedef enum logic [2:0] { + CS_X8 = 3'b000, + CS_X9 = 3'b001, + CS_X18 = 3'b010, + CS_X19 = 3'b011, + CS_X20 = 3'b100, + CS_X21 = 3'b101, + CS_X22 = 3'b110, + CS_X23 = 3'b111 + } gpr_rvc_sreg_name_e; + + typedef enum logic [2:0] { + CS_S0 = 3'b000, + CS_S1 = 3'b001, + CS_S2 = 3'b010, + CS_S3 = 3'b011, + CS_S4 = 3'b100, + CS_S5 = 3'b101, + CS_S6 = 3'b110, + CS_S7 = 3'b111 + } gpr_rvc_sreg_abi_name_e; + typedef union packed { bit [2:0] raw; gpr_rvc_name_e gpr; gpr_rvc_abi_name_e gpr_abi; } gpr_rvc_t; + typedef union packed { + bit [2:0] raw; + gpr_rvc_sreg_name_e gpr; + gpr_rvc_sreg_abi_name_e gpr_abi; + } gpr_rvc_sreg_t; + typedef union packed { bit [4:0] raw; gpr_name_e gpr; @@ -748,13 +776,6 @@ logic[6:2] funct5; } cu_type_t; - typedef struct packed { - logic[15:10] funct6; - gpr_rvc_t r1s; - logic[6:5] funct2; - gpr_rvc_t r2s; - } cmmv_type_t; - typedef struct packed { logic[15:10] funct6; logic[9:2] index; @@ -767,6 +788,13 @@ logic[5:4] spimm; } cmpp_type_t; + typedef struct packed { + logic[15:10] funct6; + gpr_rvc_sreg_t r1s; + logic[6:5] funct2; + gpr_rvc_sreg_t r2s; + } cmmv_type_t; + // Compressed instruction types typedef struct packed { logic [31:16] reserved_31_16; @@ -810,10 +838,12 @@ // and enumerated abi register names // --------------------------------------------------------------------------- typedef struct packed { - gpr_t gpr; - gpr_rvc_t gpr_rvc; - bit valid; - bit valid_gpr_rvc; + gpr_t gpr; + gpr_rvc_t gpr_rvc; + gpr_rvc_sreg_t gpr_rvc_sreg; + bit valid; + bit valid_gpr_rvc; + bit valid_gpr_rvc_sreg; } reg_operand_t; // --------------------------------------------------------------------------- diff --git a/lib/isa_decoder/isa_typedefs_csr.sv b/lib/isa_decoder/isa_typedefs_csr.sv index 99d7d09339..cb618fd4cf 100644 --- a/lib/isa_decoder/isa_typedefs_csr.sv +++ b/lib/isa_decoder/isa_typedefs_csr.sv @@ -47,6 +47,7 @@ MSCRATCHCSW = 12'h348, MSCRATCHCSWL = 12'h349, MCLICBASE = 12'h34A, + MSECCFG = 12'h747, TSELECT = 12'h7A0, TDATA1 = 12'h7A1, TDATA2 = 12'h7A2, diff --git a/lib/uvm_agents/uvma_isacov/uvma_isacov_mon.sv b/lib/uvm_agents/uvma_isacov/uvma_isacov_mon.sv index adf1842114..8a4a7a45d0 100644 --- a/lib/uvm_agents/uvma_isacov/uvma_isacov_mon.sv +++ b/lib/uvm_agents/uvma_isacov/uvma_isacov_mon.sv @@ -216,14 +216,64 @@ function void uvma_isacov_mon_c::write_rvfi_instr(uvma_rvfi_instr_seq_item_c#(IL // might also interfere with the spike implementation. // the "get_rx"-functions should no longer be needed if we supply the translated values to // the coverage model. - mon_trn.instr.c_rdrs1 = instr_asm.rd.valid ? ( instr_asm.rd.valid_gpr_rvc ? instr_asm.rd.gpr_rvc : instr_asm.rd.gpr ) - : ( instr_asm.rs1.valid_gpr_rvc ? instr_asm.rs1.gpr_rvc : instr_asm.rs1.gpr ); - mon_trn.instr.c_rdp = instr_asm.rd.valid_gpr_rvc ? instr_asm.rd.gpr_rvc : instr_asm.rd.gpr; - mon_trn.instr.c_rs1s = instr_asm.rs1.valid_gpr_rvc ? instr_asm.rs1.gpr_rvc : instr_asm.rs1.gpr; - mon_trn.instr.c_rs2s = instr_asm.rs2.valid_gpr_rvc ? instr_asm.rs2.gpr_rvc : instr_asm.rs2.gpr; - mon_trn.instr.rs1 = instr_asm.rs1.valid_gpr_rvc ? instr_asm.rs1.gpr_rvc : instr_asm.rs1.gpr; - mon_trn.instr.rs2 = instr_asm.rs2.valid_gpr_rvc ? instr_asm.rs2.gpr_rvc : instr_asm.rs1.gpr; - mon_trn.instr.rd = instr_asm.rd.valid_gpr_rvc ? instr_asm.rd.gpr_rvc : instr_asm.rd.gpr; + + if ( instr_asm.rd.valid ) begin + case (1) + instr_asm.rd.valid_gpr_rvc_sreg : begin + mon_trn.instr.c_rdrs1 = instr_asm.rd.gpr_rvc_sreg; + mon_trn.instr.c_rdp = instr_asm.rd.gpr_rvc_sreg; + mon_trn.instr.rd = instr_asm.rd.gpr_rvc_sreg; + end + instr_asm.rd.valid_gpr_rvc : begin + mon_trn.instr.c_rdrs1 = instr_asm.rd.gpr_rvc; + mon_trn.instr.c_rdp = instr_asm.rd.gpr_rvc; + mon_trn.instr.rd = instr_asm.rd.gpr_rvc; + end + default : begin + mon_trn.instr.c_rdrs1 = instr_asm.rd.gpr; + mon_trn.instr.c_rdp = instr_asm.rd.gpr; + mon_trn.instr.rd = instr_asm.rd.gpr; + end + endcase + end + + if ( instr_asm.rs1.valid ) begin + case (1) + instr_asm.rs1.valid_gpr_rvc_sreg : begin + mon_trn.instr.c_rdrs1 = instr_asm.rd.valid ? mon_trn.instr.c_rdrs1 : instr_asm.rs1.gpr_rvc_sreg; + mon_trn.instr.c_rs1s = instr_asm.rs1.gpr_rvc_sreg; + mon_trn.instr.rs1 = instr_asm.rs1.gpr_rvc_sreg; + end + instr_asm.rs1.valid_gpr_rvc : begin + mon_trn.instr.c_rdrs1 = instr_asm.rd.valid ? mon_trn.instr.c_rdrs1 : instr_asm.rs1.gpr_rvc; + mon_trn.instr.c_rs1s = instr_asm.rs1.gpr_rvc; + mon_trn.instr.rs1 = instr_asm.rs1.gpr_rvc; + end + default : begin + mon_trn.instr.c_rdrs1 = instr_asm.rd.valid ? mon_trn.instr.c_rdrs1 : instr_asm.rs1.gpr; + mon_trn.instr.c_rs1s = instr_asm.rs1.gpr; + mon_trn.instr.rs1 = instr_asm.rs1.gpr; + end + endcase + end + + if ( instr_asm.rs2.valid ) begin + case (1) + instr_asm.rs2.valid_gpr_rvc_sreg : begin + mon_trn.instr.c_rs2s = instr_asm.rs2.gpr_rvc_sreg; + mon_trn.instr.rs2 = instr_asm.rs2.gpr_rvc_sreg; + end + instr_asm.rs2.valid_gpr_rvc : begin + mon_trn.instr.c_rs2s = instr_asm.rs2.gpr_rvc; + mon_trn.instr.rs2 = instr_asm.rs2.gpr_rvc; + end + default : begin + mon_trn.instr.c_rs2s = instr_asm.rs2.gpr; + mon_trn.instr.rs2 = instr_asm.rs2.gpr; + end + endcase + end + mon_trn.instr.immi = instr_asm.imm.imm_raw_sorted; mon_trn.instr.imms = instr_asm.imm.imm_raw_sorted; mon_trn.instr.immb = instr_asm.imm.imm_raw_sorted; diff --git a/lib/uvm_agents/uvma_obi_memory/src/obj/uvma_obi_memory_cfg.sv b/lib/uvm_agents/uvma_obi_memory/src/obj/uvma_obi_memory_cfg.sv index f0681078b4..2ea3b7b6de 100644 --- a/lib/uvm_agents/uvma_obi_memory/src/obj/uvma_obi_memory_cfg.sv +++ b/lib/uvm_agents/uvma_obi_memory/src/obj/uvma_obi_memory_cfg.sv @@ -76,27 +76,29 @@ class uvma_obi_memory_cfg_c extends uvm_object; rand bit drv_slv_err_one_shot_mode; bit drv_slv_err_one_shot_flag; - rand uvma_obi_memory_drv_slv_exokay_mode_enum drv_slv_exokay_mode; - rand int unsigned drv_slv_exokay_failure_wgt; - rand int unsigned drv_slv_exokay_success_wgt; + rand uvma_obi_memory_drv_slv_exokay_mode_enum drv_slv_exokay_mode; + rand int unsigned drv_slv_exokay_failure_wgt; + rand int unsigned drv_slv_exokay_success_wgt; // Directed error generation memory address range // If the valid bit is asserted any address in range will repsond with error = 1 - bit [31:0] directed_slv_err_addr_min; - bit [31:0] directed_slv_err_addr_max; - bit directed_slv_err_valid; + bit [31:0] directed_slv_err_addr_min; + bit [31:0] directed_slv_err_addr_max; + bit directed_slv_err_valid; // Directed exokay generation memory address range // if the "valid" bit is asserted any address in range will respond // with exokay == 0 - bit [31:0] directed_slv_exokay_addr_min; - bit [31:0] directed_slv_exokay_addr_max; - bit directed_slv_exokay_valid; + bit [31:0] directed_slv_exokay_addr_min; + bit [31:0] directed_slv_exokay_addr_max; + bit directed_slv_exokay_valid; - bit [31:0] directed_slv_reservation_addr_min; - bit [31:0] directed_slv_reservation_addr_max; - bit directed_slv_reservation_valid; - bit [31:0] directed_slv_nr_reserved_words = 32'b1; + bit [31:0] directed_slv_reservation_addr_min; + bit [31:0] directed_slv_reservation_addr_max; + bit directed_slv_reservation_valid; + bit [31:0] directed_slv_nr_reserved_words = 32'b1; + + rand bit random_err_await_goahead = 0; `uvm_object_utils_begin(uvma_obi_memory_cfg_c) @@ -191,6 +193,7 @@ class uvma_obi_memory_cfg_c extends uvm_object; soft drv_slv_err_mode == UVMA_OBI_MEMORY_DRV_SLV_ERR_MODE_OK; soft drv_slv_err_one_shot_mode == 0; soft drv_slv_exokay_mode == UVMA_OBI_MEMORY_DRV_SLV_EXOKAY_MODE_SUCCESS; + soft random_err_await_goahead == 0; } constraint stall_disable_cons { @@ -335,10 +338,15 @@ function int unsigned uvma_obi_memory_cfg_c::calc_random_rvalid_latency(); endfunction : calc_random_rvalid_latency + function bit uvma_obi_memory_cfg_c::calc_random_err(bit[31:0] addr); bit err; + if (random_err_await_goahead) begin + return 0; + end + // If we are in "one-shot" mode and have already calculated an error, // then skip any new errors (until the code resets the flag) if (drv_slv_err_one_shot_mode && drv_slv_err_one_shot_flag) begin @@ -375,6 +383,7 @@ function bit uvma_obi_memory_cfg_c::calc_random_err(bit[31:0] addr); endfunction : calc_random_err + function bit uvma_obi_memory_cfg_c::calc_random_exokay(bit[31:0] addr, bit is_SCW); bit exokay; diff --git a/lib/uvm_agents/uvma_obi_memory/src/seq/uvma_obi_memory_slv_base_seq.sv b/lib/uvm_agents/uvma_obi_memory/src/seq/uvma_obi_memory_slv_base_seq.sv index ebf46798c0..484e2f2d40 100644 --- a/lib/uvm_agents/uvma_obi_memory/src/seq/uvma_obi_memory_slv_base_seq.sv +++ b/lib/uvm_agents/uvma_obi_memory/src/seq/uvma_obi_memory_slv_base_seq.sv @@ -129,18 +129,21 @@ task uvma_obi_memory_slv_base_seq_c::body(); endtask : body + task uvma_obi_memory_slv_base_seq_c::do_response(ref uvma_obi_memory_mon_trn_c mon_req); `uvm_fatal("OBI_MEMORY_SLV_SEQ", "Call to pure virtual task") endtask : do_response + function void uvma_obi_memory_slv_base_seq_c::add_latencies(uvma_obi_memory_slv_seq_item_c slv_rsp); slv_rsp.rvalid_latency = cfg.calc_random_rvalid_latency(); endfunction : add_latencies + function void uvma_obi_memory_slv_base_seq_c::add_r_fields(uvma_obi_memory_mon_trn_c mon_req, uvma_obi_memory_slv_seq_item_c slv_rsp); // This is just a convenience function @@ -157,12 +160,14 @@ function void uvma_obi_memory_slv_base_seq_c::add_r_fields(uvma_obi_memory_mon_t endfunction : add_r_fields + function void uvma_obi_memory_slv_base_seq_c::add_err(uvma_obi_memory_slv_seq_item_c slv_rsp); slv_rsp.err = cfg.calc_random_err(slv_rsp.orig_trn.address); endfunction : add_err + function void uvma_obi_memory_slv_base_seq_c::add_exokay(uvma_obi_memory_mon_trn_c mon_req, uvma_obi_memory_slv_seq_item_c slv_rsp); if (mon_req.atop[5] != 1'b1 || !(mon_req.atop[4:0] inside {5'h2, 5'h3})) begin @@ -188,6 +193,7 @@ function void uvma_obi_memory_slv_base_seq_c::add_ruser(uvma_obi_memory_slv_seq_ endfunction : add_ruser + function void uvma_obi_memory_slv_base_seq_c::add_rchk(uvma_obi_memory_slv_seq_item_c slv_rsp); if(cfg.chk_scheme == UVMA_OBI_MEMORY_CHK_TIED) begin diff --git a/lib/uvm_agents/uvma_obi_memory/src/uvma_obi_memory_assert.sv b/lib/uvm_agents/uvma_obi_memory/src/uvma_obi_memory_assert.sv index 03f3612cec..be355fcd6c 100644 --- a/lib/uvm_agents/uvma_obi_memory/src/uvma_obi_memory_assert.sv +++ b/lib/uvm_agents/uvma_obi_memory/src/uvma_obi_memory_assert.sv @@ -239,5 +239,27 @@ module uvma_obi_memory_assert `uvm_error(info_tag, $sformatf("be of 0x%01x not consistent with addr 0x%08x", $sampled(be), $sampled(addr))); + // Observing Grant Delays + + cov_gnt_delay_0: cover property ( + $rose(req) ##0 + gnt + ); + + cov_gnt_delay_1: cover property ( + $rose(req) ##0 + !gnt [*1] + ##1 + gnt + ); + + cov_gnt_delay_2: cover property ( + $rose(req) ##0 + !gnt [*2] + ##1 + gnt + ); + + endmodule : uvma_obi_memory_assert