Skip to content

Modifications for ZicsrV #695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion bin/csrtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,47 @@ def counterenwalkdouble(pathname, csr1, csr2, regs, hregs, mode):
print("#endif")
sys.stdout = sys.__stdout__


def cp_vsetvl_i_rd_nx0_rs1_x0(pathname):
with open(pathname, 'w') as outfile:
sys.stdout = outfile
sews = ["8", "16", "32", "64"]
lmuls = ["1", "2", "4", "8", "f2", "f4", "f8"]

print("// Tests for cp_vsetvl_i_rd_nx0_rs1_x0")
for sew in sews:
for lmul in lmuls:
print("\t// SEW = " + sew + ", LMUL = " + lmul)
print("\tvsetvli x8, x0, e" + sew + ", m" + lmul + ", tu, mu")
print("\tcsrr x1, vl")
print("\tRVTEST_SIGUPD(x3, x1)")
print()

for i in range(32):
if i not in [4, 12, 20, 28]: # LMUL = 3'b100 is reserved
ih = hex(i)
print(f"\t// vtype[7:0] = 0_0_{format(i >> 3, '03b')}_{format(i & 0b111, '03b')}")
print("\tli t2, " + str(ih))
print("\tcsrr x1, vl")
print("\tRVTEST_SIGUPD(x3, x1)")
print()
outfile.close

def cp_vsetivli_avl_corners(pathname):
with open(pathname, 'w') as outfile:
sys.stdout = outfile
sews = ["8", "16", "32", "64"]

print("// Tests for cp_vsetivli_avl_corners")
for sew in sews:
for i in range(32):
print("\t// SEW = " + sew + " and LMUL = 1")
print("\tvsetivli x8, " + str(i) + ", e" + sew + ", m1, tu, mu")
print("\tcsrr x1, vl")
print("\tRVTEST_SIGUPD(x3, x1)")
print()
outfile.close

# setup
seed(0) # make tests reproducible

Expand All @@ -169,7 +210,7 @@ def counterenwalkdouble(pathname, csr1, csr2, regs, hregs, mode):
mregs = ["mstatus", "mcause", "misa", "medeleg", "mideleg", "mie", "mtvec", "mcounteren", "mscratch", "mepc", "mtval", "mip", "menvcfg", "mseccfg"]
mregsh = ["mstatush", "mseccfgh", "menvcfgh", "0x312" ]# 0x312 is medelegeh; RV64 compiler isn't accepting the name
sregs = ["sstatus", "scause", "sie", "stvec", "scounteren", "senvcfg", "sscratch", "sepc", "stval", "sip", "0x120"] # 0x120 is scountinhibit, currently unsupported
uregs = ["fflags", "frm", "fcsr"]
uregs = ["fflags", "frm", "fcsr", "vtype", "vlenb", "vl", "vstart", "vxrm", "vxsat", "vcsr"]
mcntrs = ["mcycle", "mcountinhibit", "minstret",
"mhpmcounter3", "mhpmcounter4", "mhpmcounter5", "mhpmcounter6", "mhpmcounter7", "mhpmcounter8", "mhpmcounter9", "mhpmcounter10", "mhpmcounter11", "mhpmcounter12", "mhpmcounter13", "mhpmcounter14", "mhpmcounter15",
"mhpmcounter16", "mhpmcounter17", "mhpmcounter18", "mhpmcounter19", "mhpmcounter20", "mhpmcounter21", "mhpmcounter22", "mhpmcounter23", "mhpmcounter24", "mhpmcounter25", "mhpmcounter26", "mhpmcounter27", "mhpmcounter28", "mhpmcounter29", "mhpmcounter30", "mhpmcounter31",
Expand Down Expand Up @@ -241,3 +282,9 @@ def counterenwalkdouble(pathname, csr1, csr2, regs, hregs, mode):

pathname = f"{ARCH_VERIF}/tests/priv/headers/Zicntr-SWalkU.h"
counterenwalk(pathname, "scounteren", cntrs, cntrsh, "U")

pathname = f"{ARCH_VERIF}/tests/priv/headers/ZicsrV-vsetvl-Tests.h"
cp_vsetvl_i_rd_nx0_rs1_x0(pathname)

pathname = f"{ARCH_VERIF}/tests/priv/headers/ZicsrV-vsetivli-Tests.h"
cp_vsetivli_avl_corners(pathname)
180 changes: 136 additions & 44 deletions fcov/priv/ZicsrV_coverage.svh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

covergroup ZicsrV_cg with function sample(ins_t ins);
option.per_instance = 0;
`include "coverage/RISCV_coverage_standard_coverpoints_vector.svh"

//////////////////////////////////////////////////////////////////////////////////
// cp_vcsrrswc
Expand All @@ -49,11 +48,56 @@ covergroup ZicsrV_cg with function sample(ins_t ins);

cp_vcsrrswc: cross vcsrs, csrops;

//////////////////////////////////////////////////////////////////////////////////
// cp_vcsrs_walking1s
// attempt to set all the writable CSR bit fields by writing all XLEN 1-hot
//////////////////////////////////////////////////////////////////////////////////
writable_vcsrs : coverpoint ins.current.insn[31:20] {
bins vstart = {12'h008};
bins vxsat = {12'h009};
bins vxrm = {12'h00A};
bins vcsr = {12'h00F};
}

csrw : coverpoint ins.current.insn {
wildcard bins csrrw = {32'b????????????_?????_001_?????_1110011};
}

walking_ones_rs1: coverpoint $clog2(ins.current.rs1_val) iff ($onehot(ins.current.rs1_val)) {
bins b_1[] = { [0:`XLEN-1] };
}

cp_vcsrs_walking1s: cross writable_vcsrs, csrw, walking_ones_rs1;

//////////////////////////////////////////////////////////////////////////////////
// cp_mstatus_vs_*
// tests mstatus ability to set clean and initial to dirty only when supposed to
//////////////////////////////////////////////////////////////////////////////////

// ensures vd updates
//cross vtype_prev_vill_clear, vstart_zero, vl_nonzero, no_trap;
std_vec: coverpoint {get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vtype", "vill") == 0 &
get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vstart", "vstart") == 0 &
get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vl", "vl") != 0 &
ins.trap == 0
}
{
bins true = {1'b1};
}

//cross vtype_prev_vill_clear, vstart_zero, vl_nonzero;
std_trap_vec : coverpoint {get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vtype", "vill") == 0 &
get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vstart", "vstart") == 0 &
get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vl", "vl") != 0
}
{
bins true = {1'b1};
}

misa_v_active : coverpoint get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "misa", "exts")[21] {
bins vector = {1};
}

vector_vector_arithmetic_instruction: coverpoint ins.current.insn[14:0] {
wildcard bins arithmetic_vv_opcode = {15'b000_?????_1010111};
}
Expand Down Expand Up @@ -113,47 +157,66 @@ covergroup ZicsrV_cg with function sample(ins_t ins);

// attempt to set lmul to all values
vset_lmul: coverpoint ins.prev.insn[22:20] {
// autofill 000-111
// autofill 000-111, ignore 3'b100 (reserved)
ignore_bins reserved = {3'b100};
}

// attempt to set sew to all values
vset_sew: coverpoint ins.prev.insn[25:23] {
// autofill 000-111
// autofill 000-011
ignore_bins reserved_100 = {3'b100};
ignore_bins reserved_101 = {3'b101};
ignore_bins reserved_110 = {3'b110};
ignore_bins reserved_111 = {3'b111};
}

// rs2 in vsetvl is written to vtype
rs2_vtype_legal: coverpoint ins.current.rs2_val[`XLEN-1:8] {
bins legal = {0};
}

rs2_lmul_sew: coverpoint ins.current.rs2_val[5:0] {
// autofill all combinations of lmul and sew
rs2_lmul: coverpoint ins.current.rs2_val[2:0] {
// autofill all combinations of lmul, ignore 3'b100 (reserved)
ignore_bins reserved = {3'b100};
}

rs2_sew : coverpoint ins.current.rs2_val[5:3] {
// autofill all combinations of sew
ignore_bins reserved_100 = {3'b100};
ignore_bins reserved_101 = {3'b101};
ignore_bins reserved_110 = {3'b110};
ignore_bins reserved_111 = {3'b111};
}

cp_sew_lmul_vsetvl: cross vsetvl_instruction, rs2_vtype_legal, rs2_lmul_sew;
cp_sew_lmul_vsetvl: cross vsetvl_instruction, rs2_vtype_legal, rs2_lmul, rs2_sew;
cp_sew_lmul_vset_i_vli: cross vset_i_vli_instructions, vset_sew, vset_lmul;

//////////////////////////////////////////////////////////////////////////////////
// cr_vill_vset*
// writes vtype with legal lmul and sew values starting with vill = 1
//////////////////////////////////////////////////////////////////////////////////

rs2_lmulge1_sew8: coverpoint ins.current.rs2_val[7:0] {
wildcard bins lmul_one = {8'b??_000_000};
wildcard bins lmul_two = {8'b??_000_001};
wildcard bins lmul_four = {8'b??_000_010};
wildcard bins lmul_eight = {8'b??_000_011};
vtype_prev_vill_set: coverpoint get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vtype", "vill") {
bins vill_set = {1};
}

vset_lmulge1: coverpoint ins.current.insn[22:20] {
bins one = {3'b000};
bins two = {3'b001};
bins four = {3'b010};
bins eight = {3'b011};
vtype_lmul_8: coverpoint get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vtype", "vlmul") {
bins two = {3};
}

vset_sew8: coverpoint ins.current.insn[25:23] {
bins target = {3'b000};
vtype_all_sew_supported: coverpoint get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vtype", "vsew") {
`ifdef SEW8_SUPPORTED
bins eight = {0};
`endif
`ifdef SEW16_SUPPORTED
bins sixteen = {1};
`endif
`ifdef SEW32_SUPPORTED
bins thirtytwo = {2};
`endif
`ifdef SEW64_SUPPORTED
bins sixtyfour = {3};
`endif
}

cp_vill_vsetvl: cross vsetvl_instruction, vtype_prev_vill_set, rs2_vtype_legal, vtype_all_sew_supported, vtype_lmul_8;
Expand All @@ -172,18 +235,7 @@ covergroup ZicsrV_cg with function sample(ins_t ins);
cp_vill_vsetvl_rs2_vill : cross vsetvl_instruction, vtype_prev_vill_set, rs2_vtype_legal, vtype_all_sew_supported, vtype_lmul_8, rs2_vill_set;

//////////////////////////////////////////////////////////////////////////////////
// cp_vtype_walking1s
// attempts to write vtype with a 1 in every location
//////////////////////////////////////////////////////////////////////////////////

walking_ones_rs2: coverpoint $clog2(ins.current.rs2_val) iff ($onehot(ins.current.rs2_val)) {
bins b_1[] = { [0:`XLEN-1] };
}

cp_vtype_walking1s : cross vsetvl_instruction, walking_ones_rs2;

//////////////////////////////////////////////////////////////////////////////////
// cp_vset_vill
// cp_vsetvl_rs2_vill
// writes a 1 to the vill bit with the rest of the register being a valid configuration
//////////////////////////////////////////////////////////////////////////////////

Expand All @@ -195,7 +247,11 @@ covergroup ZicsrV_cg with function sample(ins_t ins);
bins lmul1 = {3'b000};
}

cp_vset_vill : cross vsetvl_instruction, rs2_vill_set, rs2_sew_supported, rs2_lmul_1, rs2_vtype_legal, vtype_prev_vill_clear;
vtype_prev_vill_clear: coverpoint get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vtype", "vill") {
bins vill_not_set = {0};
}

cp_vsetvl_rs2_vill : cross vsetvl_instruction, rs2_vill_set, rs2_sew_supported, rs2_lmul_1, rs2_vtype_legal, vtype_prev_vill_clear;

//////////////////////////////////////////////////////////////////////////////////
// cp_vtype_vill_set_vl_0
Expand All @@ -206,13 +262,28 @@ covergroup ZicsrV_cg with function sample(ins_t ins);
bins nonzero = { [0:`XLEN-1] };
}

vl_nonzero: coverpoint get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vl", "vl") {
//Any value between max and 1
bins target = {[`XLEN'h10000:`XLEN'h1]};
}

cp_vtype_vill_set_vl_0 : cross vsetvl_instruction, rs1_non_zero, rs2_vill_set, vl_nonzero;

//////////////////////////////////////////////////////////////////////////////////
// cp_vsetvl_i_rd_*_rs1_*
// checks behavior regarding setting the vl register to max or leave unchanged
//////////////////////////////////////////////////////////////////////////////////

vsetvl_i_instructions: coverpoint ins.current.insn {
wildcard bins vsetvli = {32'b0000_?_?_???_???_?????_111_?????_1010111};
wildcard bins vsetvl = {32'b1000000_?????_?????_111_?????_1010111};
}

vl_not_max: coverpoint (get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vl", "vl") ==
get_vtype_vlmax(ins.hart, ins.issue, `SAMPLE_BEFORE)) {
bins target = {1'b0};
}

rd_n0 : coverpoint ins.current.insn[11:7] {
bins not_zero = {[31:1]};
}
Expand All @@ -230,19 +301,35 @@ covergroup ZicsrV_cg with function sample(ins_t ins);
bins true = {1};
}

cp_vset_i_vli_rd_n0_rs1_x0_sew8 : cross vset_i_vli_instructions, vl_not_max, rd_n0, rs1_x0, vtype_sew_8, vtype_all_lmul_supported_sew8;
cp_vset_i_vli_rd_n0_rs1_x0_sew16 : cross vset_i_vli_instructions, vl_not_max, rd_n0, rs1_x0, vtype_sew_16, vtype_all_lmul_supported_sew16;
cp_vset_i_vli_rd_n0_rs1_x0_sew32 : cross vset_i_vli_instructions, vl_not_max, rd_n0, rs1_x0, vtype_sew_32, vtype_all_lmul_supported_sew32;
cp_vset_i_vli_rd_n0_rs1_x0_sew64 : cross vset_i_vli_instructions, vl_not_max, rd_n0, rs1_x0, vtype_sew_64, vtype_all_lmul_supported_sew64;

cp_vset_i_vli_rd_x0_rs1_x0 : cross vset_i_vli_instructions, vl_nonzero, rd_x0, rs1_x0, vset_i_vli_vlmax_unchanged;
vtype_all_lmul_supported : coverpoint get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vtype", "vlmul") {
`ifdef LMULf8_SUPPORTED
bins eigth = {5};
`endif
`ifdef LMULf4_SUPPORTED
bins fourth = {6};
`endif
`ifdef LMULf2_SUPPORTED
bins half = {7};
`endif
bins one = {0};
bins two = {1};
bins four = {2};
bins eight = {3};
}

cp_vsetvl_i_rd_nx0_rs1_x0 : cross vsetvl_i_instructions, vl_not_max, rd_n0, rs1_x0, vtype_all_sew_supported, vtype_all_lmul_supported;
cp_vsetvl_i_rd_x0_rs1_x0 : cross vsetvl_i_instructions, vl_nonzero, rd_x0, rs1_x0, vset_i_vli_vlmax_unchanged;

//////////////////////////////////////////////////////////////////////////////////
// cp_vsetvl_i_avl_*
// tests corner case avl behavior on the vset instructions
//////////////////////////////////////////////////////////////////////////////////

rs1_le_vlmax : coverpoint (ins.current.rs1_val <= get_vtype_vlmax(ins.hart, ins.issue, `SAMPLE_BEFORE)) {
rs1_eq_zero : coverpoint (ins.current.rs1_val == 0 & ins.current.insn[19:15] != 0) {
bins true = {1};
}

rs1_eq_vlmax : coverpoint (ins.current.rs1_val == get_vtype_vlmax(ins.hart, ins.issue, `SAMPLE_BEFORE)) {
bins true = {1};
}

Expand All @@ -251,13 +338,12 @@ covergroup ZicsrV_cg with function sample(ins_t ins);
bins true = {1};
}

rs1_ge_2x_vlmax : coverpoint (ins.current.rs1_val >= 2 * get_vtype_vlmax(ins.hart, ins.issue, `SAMPLE_BEFORE)) {
rs1_eq_2x_vlmax : coverpoint (ins.current.rs1_val == 2 * get_vtype_vlmax(ins.hart, ins.issue, `SAMPLE_BEFORE)) {
bins true = {1};
}

vsetvl_i_instructions: coverpoint ins.current.insn {
wildcard bins vsetvli = {32'b0000_?_?_???_???_?????_111_?????_1010111};
wildcard bins vsetvl = {32'b1000000_?????_?????_111_?????_1010111};
rs1_gt_2x_vlmax : coverpoint (ins.current.rs1_val > 2 * get_vtype_vlmax(ins.hart, ins.issue, `SAMPLE_BEFORE)) {
bins true = {1};
}

vsetivli_instruction : coverpoint ins.current.insn {
Expand All @@ -268,9 +354,15 @@ covergroup ZicsrV_cg with function sample(ins_t ins);
// all generated bins for imm corners
}

cp_vsetvl_i_avl_le_vlmax : cross vsetvl_i_instructions, rs1_le_vlmax;
vtype_lmul_1: coverpoint get_csr_val(ins.hart, ins.issue, `SAMPLE_BEFORE, "vtype", "vlmul") {
bins one = {0};
}

cp_vsetvl_i_avl_eq_zero : cross vsetvl_i_instructions, rs1_eq_zero;
cp_vsetvl_i_avl_eq_vlmax : cross vsetvl_i_instructions, rs1_eq_vlmax;
cp_vsetvl_i_avl_lt_2x_vlmax : cross vsetvl_i_instructions, rs1_lt_2x_vlmax_gt_vlmax;
cp_vsetvl_i_avl_ge_2x_vlmax : cross vsetvl_i_instructions, rs1_ge_2x_vlmax;
cp_vsetvl_i_avl_eq_2x_vlmax : cross vsetvl_i_instructions, rs1_eq_2x_vlmax;
cp_vsetvl_i_avl_gt_2x_vlmax : cross vsetvl_i_instructions, rs1_gt_2x_vlmax;

cp_vsetivli_avl_corners : cross vsetivli_instruction, vtype_all_sew_supported, imm5_corners, vtype_lmul_1;

Expand Down