chipsalliance / chipsalliance/riscv-vector-tests

[load/store] Add EEW!=SEW test coverage and restructure test generator headers

Open
#91 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
118
Forks
40
PR merge metrics
No merged PRs in 30d

Description

## Summary

Two improvements to the load/store instruction test generator:

1. **EEW != SEW test coverage** — generator previously only produced tests where EEW = SEW. This extends it to cover all valid EEW/EMUL combinations for a given SEW/LMUL pair.
2. **Restructured headers** — split into a group header (LMUL + Mask, emitted once per group) and a lightweight per-test sub-header (VL, SEW, EEW, EMUL, Policy), removing the redundant CSR initialization comment from load/store tests where it is not needed. Other instruction types are not affected.

---

## Problem

### 1. EEW = SEW only

The generator currently only iterates `EEW = SEW`, so narrower element width variants (e.g. `vle8.v` with `SEW=e16, LMUL=mf4, EEW=e8, EMUL=mf8`) are never tested.

### 2. Noisy and misleading headers

Every test emits a flat header that includes `# Initialize rounding mode CSR` and `csrwi vxrm, 0` even for plain load/store instructions where the rounding mode has no effect.

Current header:

```asm
# Generating tests for VL: 4, LMUL: mf8, SEW: e8, Mask: false
# Initialize rounding mode CSR
csrwi vxrm, 0 # rnu (round-to-nearest-up)
```

---

## Proposed fix

### New header functions in `insn.go`

Group header (once per LMUL/Mask group):

```go
func (c *combination) initializeHeader() string {
str := fmt.Sprintf(`# =============================================================
# Generating tests for LMUL: %s, Mask: %v
# =============================================================`, c.LMUL.String(), c.Mask)
return str
}
```

Per-test sub-header (includes full EEW/EMUL detail, no CSR lines):

```go
func (c *combination) initializeWithSEW(currentSew SEW, emul LMUL, testCaseCounter int) string {
str := fmt.Sprintf(`# ---------------------------------------------------------------------------------------------------
# Generating test (#%d) for VL: %d, SEW: %s, LMUL: %s, EEW: %s, EMUL: %s, Mask: %v
# ---------------------------------------------------------------------------------------------------
`, testCaseCounter, c.Vl, currentSew.String(), c.LMUL.String(), c.SEW.String(), emul.String(), c.Mask)
return str
}
```

The original `initialize()` is kept untouched for all other instruction types that need CSR setup.

---

## Generated output (`vle8.S`)

Header structure (from `grep "Generating test"`):
Generating tests for LMUL: mf8, Mask: false
Generating test (#1) for VL: 4, SEW: e8, LMUL: mf8, EEW: e8, EMUL: mf8, Mask: false
Generating test (#2) for VL: 0, SEW: e8, LMUL: mf8, EEW: e8, EMUL: mf8, Mask: false
Generating test (#3) for VL: 1, SEW: e8, LMUL: mf8, EEW: e8, EMUL: mf8, Mask: false
Generating tests for LMUL: mf4, Mask: false
Generating test (#7) for VL: 8, SEW: e8, LMUL: mf4, EEW: e8, EMUL: mf4, Mask: false
Generating test (#8) for VL: 0, SEW: e8, LMUL: mf4, EEW: e8, EMUL: mf4, Mask: false
Generating test (#9) for VL: 1, SEW: e8, LMUL: mf4, EEW: e8, EMUL: mf4, Mask: false
Generating test (#10) for VL: 4, SEW: e16, LMUL: mf4, EEW: e8, EMUL: mf8, Mask: false <- EEW != SEW
Generating test (#11) for VL: 0, SEW: e16, LMUL: mf4, EEW: e8, EMUL: mf8, Mask: false <- EEW != SEW
Generating test (#12) for VL: 1, SEW: e16, LMUL: mf4, EEW: e8, EMUL: mf8, Mask: false <- EEW != SEW
Generating tests for LMUL: mf2, Mask: false
Generating test (#19) for VL: 16, SEW: e8, LMUL: mf2, EEW: e8, EMUL: mf2, Mask: false
Generating test (#22) for VL: 8, SEW: e16, LMUL: mf2, EEW: e8, EMUL: mf4, Mask: false <- EEW != SEW
Generating test (#25) for VL: 4, SEW: e32, LMUL: mf2, EEW: e8, EMUL: mf8, Mask: false <- EEW != SEW
Generating tests for LMUL: m1, Mask: false
Generating test (#37) for VL: 32, SEW: e8, LMUL: m1, EEW: e8, EMUL: m1, Mask: false
Generating test (#40) for VL: 16, SEW: e16, LMUL: m1, EEW: e8, EMUL: mf2, Mask: false <- EEW != SEW
Generating test (#43) for VL: 8, SEW: e32, LMUL: m1, EEW: e8, EMUL: mf4, Mask: false <- EEW != SEW
Generating test (#46) for VL: 4, SEW: e64, LMUL: m1, EEW: e8, EMUL: mf8, Mask: false <- EEW != SEW
Generating tests for LMUL: m1, Mask: true
Generating test (#49) for VL: 32, SEW: e8, LMUL: m1, EEW: e8, EMUL: m1, Mask: true
Generating test (#52) for VL: 16, SEW: e16, LMUL: m1, EEW: e8, EMUL: mf2, Mask: true <- EEW != SEW
Generating test (#55) for VL: 8, SEW: e32, LMUL: m1, EEW: e8, EMUL: mf4, Mask: true <- EEW != SEW
Generating test (#58) for VL: 4, SEW: e64, LMUL: m1, EEW: e8, EMUL: mf8, Mask: true <- EEW != SEW

Full generated assembly for a single test (small portion):

```asm
# =============================================================
# Generating tests for LMUL: mf8, Mask: false
# =============================================================
# ---------------------------------------------------------------------------------------------------
# Generating test (#1) for VL: 4, SEW: e8, LMUL: mf8, EEW: e8, EMUL: mf8, Mask: false
# ---------------------------------------------------------------------------------------------------

# Move a0 to test data area.
la a0, testdata
li a5, 0
add a0, a0, a5

# Load data into v0 register (Full Register Load).
vsetvli t1, x0, e32,m1,tu,mu
vle32.v v0, (a0)

# Move a0 to test data area.
la a0, testdata
li a5, 32
add a0, a0, a5

# Load data into v8 register (Full Register Load).
vsetvli t1, x0, e8,m1,tu,mu
vle8.v v8, (a0)

# Move a0 to test data area.
la a0, testdata
li a5, 64
add a0, a0, a5
# ============== TEST BEGIN ==============
li t0, 4
vsetvli t1, t0, e8,mf8,tu,mu
vle8.v v8, (a0)
# ============== TEST END ==============

# Move a0 to result data area.
la a0, resultdata

# Store v8 register into result data area (Full Register Store).
vsetvli t1, x0, e8,m1,tu,mu
vse8.v v8, (a0)

# ====================== SELF VERIFYING BEGIN ======================

TEST_CASE(2, t0, 0xb1b3d4620f020100, ld t0, 0(a0); addi a0, a0, 8)
TEST_CASE(3, t0, 0x5f03517aa30230ee, ld t0, 0(a0); addi a0, a0, 8)
TEST_CASE(4, t0, 0x7dcf27ed2365efac, ld t0, 0(a0); addi a0, a0, 8)
TEST_CASE(5, t0, 0xa6750f800ba3527, ld t0, 0(a0); addi a0, a0, 8)

# ====================== SELF VERIFYING END ======================
# ------------------------------------------------------------------
```

Verified against `v256x64machine` for `vle8.S`.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in insn.go by tracing the existing load/store generator path and its EEW = SEW iteration. Compare the proposed group and per-test headers with the generated vle8.S output, then verify the result against v256x64machine and confirm that other instruction types retain their existing headers.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
testing-qa, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.