88
99"""SmV privileged test generator: vector CSRs and vtype/vl/vstart behavior in M-mode."""
1010
11+ from testgen .asm .csr import gen_csr_read_sigupd
1112from testgen .asm .helpers import comment_banner
1213from testgen .data .state import TestData
1314from testgen .priv .registry import add_priv_test_generator
@@ -51,14 +52,14 @@ def _gen_vcsrrswc(test_data: TestData, temp_reg: int) -> list[str]:
5152 ]
5253 lines .extend (_set_vs (vs = 3 , temp_reg = temp_reg ))
5354 lines .extend (_vector_setup (temp_reg ))
54- save_reg = test_data .int_regs .get_register ( )
55+ save_reg , check_reg = test_data .int_regs .get_registers ( 2 )
5556 lines .append (f"LI(x{ save_reg } , -1) # all 1s mask for csr ops" )
5657 for csr in _VECTOR_CSRS :
5758 for op_name , op in (("csrrs" , "CSRS" ), ("csrrc" , "CSRC" ), ("csrrw" , "CSRW" )):
5859 lines .append (test_data .add_testcase (f"{ csr } _{ op_name } " , coverpoint , _CG ))
5960 lines .append (f"{ op } ({ csr } , x{ save_reg } ) # { op_name } { csr } " )
60- lines .append ("nop" )
61- test_data .int_regs .return_registers ([save_reg ])
61+ lines .append (gen_csr_read_sigupd ( check_reg , ( csr , None ), test_data ) )
62+ test_data .int_regs .return_registers ([save_reg , check_reg ])
6263 return lines
6364
6465
@@ -72,26 +73,10 @@ def _gen_vcsrs_walking1s(test_data: TestData, temp_reg: int) -> list[str]:
7273 ]
7374 lines .extend (_set_vs (vs = 3 , temp_reg = temp_reg ))
7475 lines .extend (_vector_setup (temp_reg ))
75- walk_reg , mask_reg = test_data .int_regs .get_registers (2 )
76- for csr in _VECTOR_CSRS_WR :
77- lines .append (f"# walking-1s on { csr } " )
78- lines .append (f"LI(x{ mask_reg } , -1) # all 1s" )
79- lines .append (f"LI(x{ walk_reg } , 1) # one-hot starting at bit 0" )
80- # We need to walk all XLEN bits; emit for both 32 and 64 via #if
81- lines .append (".rept __riscv_xlen" )
82- # Note: .rept doesn't access __riscv_xlen as a number; emit per-bit explicitly with #if guard
83- lines .append (".endr" )
84- # Replace the .rept stub with explicit unroll: emit bit-by-bit with #if for RV64 high bits
85- lines = lines [
86- : lines .index (
87- comment_banner (
88- coverpoint , "csrrw walking-1s into vstart/vxsat/vxrm/vcsr (covers walking_ones_rs1 bins 0..XLEN-1)"
89- )
90- )
91- + 1
92- ]
93- lines .extend (_set_vs (vs = 3 , temp_reg = temp_reg ))
94- lines .extend (_vector_setup (temp_reg ))
76+ # Walk one bit at a time, reading the CSR back after each write so the
77+ # signature captures how the DUT latched it. RV64 high bits are guarded by
78+ # #if so the RV32 build only emits the low 32.
79+ walk_reg , mask_reg , check_reg = test_data .int_regs .get_registers (3 )
9580 for csr in _VECTOR_CSRS_WR :
9681 lines .append (f"# walking-1s on { csr } " )
9782 lines .append (f"LI(x{ mask_reg } , -1) # all 1s" )
@@ -100,15 +85,17 @@ def _gen_vcsrs_walking1s(test_data: TestData, temp_reg: int) -> list[str]:
10085 lines .append (f"CSRC({ csr } , x{ mask_reg } ) # clear all bits" )
10186 lines .append (test_data .add_testcase (f"{ csr } _bit_{ i } " , coverpoint , _CG ))
10287 lines .append (f"CSRW({ csr } , x{ walk_reg } ) # walking-1 bit { i } " )
88+ lines .append (gen_csr_read_sigupd (check_reg , (csr , None ), test_data ))
10389 lines .append (f"slli x{ walk_reg } , x{ walk_reg } , 1" )
10490 lines .append ("#if __riscv_xlen == 64" )
10591 for i in range (32 , 64 ):
10692 lines .append (f"CSRC({ csr } , x{ mask_reg } ) # clear all bits" )
10793 lines .append (test_data .add_testcase (f"{ csr } _bit_{ i } " , coverpoint , _CG ))
10894 lines .append (f"CSRW({ csr } , x{ walk_reg } ) # walking-1 bit { i } " )
95+ lines .append (gen_csr_read_sigupd (check_reg , (csr , None ), test_data ))
10996 lines .append (f"slli x{ walk_reg } , x{ walk_reg } , 1" )
11097 lines .append ("#endif" )
111- test_data .int_regs .return_registers ([walk_reg , mask_reg ])
98+ test_data .int_regs .return_registers ([walk_reg , mask_reg , check_reg ])
11299 return lines
113100
114101
@@ -495,11 +482,12 @@ def _gen_vstart_oob(test_data: TestData, temp_reg: int) -> list[str]:
495482 coverpoint = "cp_vstart_out_of_bounds"
496483 lines = [comment_banner (coverpoint , "csrrw vstart with rs1 = 2^16 (above max VLEN-1)" )]
497484 lines .extend (_set_vs (vs = 3 , temp_reg = temp_reg ))
498- rs1_reg = test_data .int_regs .get_register ( )
485+ rs1_reg , check_reg = test_data .int_regs .get_registers ( 2 )
499486 lines .append (f"LI(x{ rs1_reg } , 0x10000) # 2^16" )
500487 lines .append (test_data .add_testcase ("vstart_oob" , coverpoint , _CG ))
501488 lines .append (f"CSRW(vstart, x{ rs1_reg } )" )
502- test_data .int_regs .return_registers ([rs1_reg ])
489+ lines .append (gen_csr_read_sigupd (check_reg , ("vstart" , None ), test_data ))
490+ test_data .int_regs .return_registers ([rs1_reg , check_reg ])
503491 return lines
504492
505493
0 commit comments