Skip to content

Commit 8860071

Browse files
frm coverpoints: sweep all 5 fcsr.frm values for dyn rounding mode
1 parent 140c176 commit 8860071

3 files changed

Lines changed: 67 additions & 22 deletions

File tree

generators/testgen/src/testgen/coverpoints/cp_fp_reg_edges.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,28 @@ def make_fs1_edges(instr_name: str, instr_type: str, coverpoint: str, test_data:
3030

3131
cross_frm = "_frm" in coverpoint
3232

33-
frm_modes = ("dyn", "rdn", "rmm", "rne", "rtz", "rup") if cross_frm else [None]
33+
# For dyn we sweep all 5 legal fcsr.frm values explicitly; relying on a random pick
34+
# lands on rne 20% of the time and hides a DUT that ignores fcsr.frm.
35+
if cross_frm:
36+
frm_variants: list[tuple[str | None, int | None]] = [("dyn", v) for v in range(5)]
37+
frm_variants += [(m, None) for m in ("rdn", "rmm", "rne", "rtz", "rup")]
38+
else:
39+
frm_variants = [(None, None)]
3440

3541
test_chunks: list[TestChunk] = []
3642
for edge_val in edges:
37-
for frm_mode in frm_modes:
38-
params = generate_random_params(test_data, instr_type, exclude_regs=[0], fs1val=edge_val, frm=frm_mode)
39-
bin_name = f"b{edge_val:#x}{f'_{frm_mode}' if frm_mode is not None else ''}"
40-
desc = f"{coverpoint} (Test source fs1 value = {test_data.flen_format_str.format(edge_val)}{f', frm = {frm_mode}' if frm_mode is not None else ''})"
43+
for frm_mode, csr_val in frm_variants:
44+
params = generate_random_params(
45+
test_data, instr_type, exclude_regs=[0], fs1val=edge_val, frm=frm_mode, csr_frm_val=csr_val
46+
)
47+
frm_tag = ""
48+
if frm_mode is not None:
49+
frm_tag = f"_{frm_mode}{csr_val}" if csr_val is not None else f"_{frm_mode}"
50+
bin_name = f"b{edge_val:#x}{frm_tag}"
51+
desc_tag = ""
52+
if frm_mode is not None:
53+
desc_tag = f", frm = {frm_mode}" + (f", fcsr.frm = {csr_val}" if csr_val is not None else "")
54+
desc = f"{coverpoint} (Test source fs1 value = {test_data.flen_format_str.format(edge_val)}{desc_tag})"
4155
tc = format_single_testcase(instr_name, instr_type, test_data, params, desc, bin_name, coverpoint)
4256
test_chunks.append(tc)
4357
return_test_regs(test_data, params)

generators/testgen/src/testgen/coverpoints/cp_frm.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,22 @@ def make_frm(instr_name: str, instr_type: str, coverpoint: str, test_data: TestD
2121
if coverpoint not in ["cp_frm_2", "cp_frm_3", "cp_frm_4"]: # TODO: Why are these variants needed?
2222
raise ValueError(f"Unknown cp_frm coverpoint variant: {coverpoint} for {instr_name}")
2323

24-
frm_modes = ("dyn", "rdn", "rmm", "rne", "rtz", "rup")
24+
# Static modes encode rm in the instruction. For dyn, rm=111 in the encoding and the
25+
# actual rounding comes from fcsr.frm, so we sweep all 5 legal frm values explicitly
26+
# rather than relying on a random pick that lands on rne (the power-on default) 20% of
27+
# the time and silently agrees with a DUT that ignores fcsr.frm.
28+
frm_variants: list[tuple[str, int | None]] = [("dyn", v) for v in range(5)]
29+
frm_variants += [(m, None) for m in ("rdn", "rmm", "rne", "rtz", "rup")]
30+
2531
test_chunks: list[TestChunk] = []
26-
for frm_mode in frm_modes:
27-
params = generate_random_params(test_data, instr_type, exclude_regs=[0], frm=frm_mode)
28-
desc = f"{coverpoint} (Test frm, mode = {frm_mode})"
29-
tc = format_single_testcase(instr_name, instr_type, test_data, params, desc, f"b{frm_mode}", coverpoint)
32+
for frm_mode, csr_val in frm_variants:
33+
params = generate_random_params(
34+
test_data, instr_type, exclude_regs=[0], frm=frm_mode, csr_frm_val=csr_val
35+
)
36+
bin_name = f"b{frm_mode}{csr_val}" if csr_val is not None else f"b{frm_mode}"
37+
desc_suffix = f", fcsr.frm = {csr_val}" if csr_val is not None else ""
38+
desc = f"{coverpoint} (Test frm, mode = {frm_mode}{desc_suffix})"
39+
tc = format_single_testcase(instr_name, instr_type, test_data, params, desc, bin_name, coverpoint)
3040
test_chunks.append(tc)
3141
return_test_regs(test_data, params)
3242

generators/testgen/src/testgen/coverpoints/cr_fp_reg_edges.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,29 @@ def make_cr_fs1_fs2_edges(instr_name: str, instr_type: str, coverpoint: str, tes
3434

3535
cross_frm = "_frm" in coverpoint
3636

37-
frm_modes = ("dyn", "rdn", "rmm", "rne", "rtz", "rup") if cross_frm else [None]
37+
# For dyn we sweep all 5 legal fcsr.frm values explicitly rather than picking one
38+
# randomly, so a DUT that ignores fcsr.frm can't slip past on the rne case.
39+
if cross_frm:
40+
frm_variants: list[tuple[str | None, int | None]] = [("dyn", v) for v in range(5)]
41+
frm_variants += [(m, None) for m in ("rdn", "rmm", "rne", "rtz", "rup")]
42+
else:
43+
frm_variants = [(None, None)]
3844

3945
test_chunks: list[TestChunk] = []
4046
for edge_val1 in edges1:
4147
for edge_val2 in edges2:
42-
# Explicit rounding modes (if needed)
43-
for frm_mode in frm_modes:
48+
for frm_mode, csr_val in frm_variants:
4449
params = generate_random_params(
45-
test_data, instr_type, exclude_regs=[0], fs1val=edge_val1, fs2val=edge_val2, frm=frm_mode
50+
test_data, instr_type, exclude_regs=[0],
51+
fs1val=edge_val1, fs2val=edge_val2,
52+
frm=frm_mode, csr_frm_val=csr_val,
4653
)
47-
bin_name = f"fs1val={edge_val1:#x}, fs2val={edge_val2:#x}, frm={frm_mode}"
48-
desc = f"{coverpoint} (Test source fs1 = {test_data.flen_format_str.format(edge_val1)} fs2 = {test_data.flen_format_str.format(edge_val2)}{f', frm = {frm_mode}' if frm_mode is not None else ''})"
54+
frm_label = "none" if frm_mode is None else (f"{frm_mode}{csr_val}" if csr_val is not None else frm_mode)
55+
bin_name = f"fs1val={edge_val1:#x}, fs2val={edge_val2:#x}, frm={frm_label}"
56+
desc_tag = ""
57+
if frm_mode is not None:
58+
desc_tag = f", frm = {frm_mode}" + (f", fcsr.frm = {csr_val}" if csr_val is not None else "")
59+
desc = f"{coverpoint} (Test source fs1 = {test_data.flen_format_str.format(edge_val1)} fs2 = {test_data.flen_format_str.format(edge_val2)}{desc_tag})"
4960
tc = format_single_testcase(instr_name, instr_type, test_data, params, desc, bin_name, coverpoint)
5061
test_chunks.append(tc)
5162
return_test_regs(test_data, params)
@@ -71,18 +82,28 @@ def make_cr_fs1_fs3_edges(instr_name: str, instr_type: str, coverpoint: str, tes
7182

7283
cross_frm = "_frm" in coverpoint
7384

74-
frm_modes = ("dyn", "rdn", "rmm", "rne", "rtz", "rup") if cross_frm else [None]
85+
# See note in make_cr_fs1_fs2_edges — dyn is expanded into 5 explicit fcsr.frm values.
86+
if cross_frm:
87+
frm_variants: list[tuple[str | None, int | None]] = [("dyn", v) for v in range(5)]
88+
frm_variants += [(m, None) for m in ("rdn", "rmm", "rne", "rtz", "rup")]
89+
else:
90+
frm_variants = [(None, None)]
7591

7692
test_chunks: list[TestChunk] = []
7793
for edge_val1 in edges1:
7894
for edge_val2 in edges2:
79-
# Explicit rounding modes (if needed)
80-
for frm_mode in frm_modes:
95+
for frm_mode, csr_val in frm_variants:
8196
params = generate_random_params(
82-
test_data, instr_type, exclude_regs=[0], fs1val=edge_val1, fs3val=edge_val2, frm=frm_mode
97+
test_data, instr_type, exclude_regs=[0],
98+
fs1val=edge_val1, fs3val=edge_val2,
99+
frm=frm_mode, csr_frm_val=csr_val,
83100
)
84-
desc = f"{coverpoint} (Test source fs1 = {test_data.flen_format_str.format(edge_val1)} fs3 = {test_data.flen_format_str.format(edge_val2)}{f', frm = {frm_mode}' if frm_mode is not None else ''})"
85-
bin_name = f"fs1val={edge_val1:#x}, fs3val={edge_val2:#x}, frm={frm_mode}"
101+
frm_label = "none" if frm_mode is None else (f"{frm_mode}{csr_val}" if csr_val is not None else frm_mode)
102+
bin_name = f"fs1val={edge_val1:#x}, fs3val={edge_val2:#x}, frm={frm_label}"
103+
desc_tag = ""
104+
if frm_mode is not None:
105+
desc_tag = f", frm = {frm_mode}" + (f", fcsr.frm = {csr_val}" if csr_val is not None else "")
106+
desc = f"{coverpoint} (Test source fs1 = {test_data.flen_format_str.format(edge_val1)} fs3 = {test_data.flen_format_str.format(edge_val2)}{desc_tag})"
86107
tc = format_single_testcase(instr_name, instr_type, test_data, params, desc, bin_name, coverpoint)
87108
test_chunks.append(tc)
88109
return_test_regs(test_data, params)

0 commit comments

Comments
 (0)