OXYGENHUB
# 2980b7b6d7cd enhanced-x16-emulator / tests / check_vera_version.py
5.4 KiB · Python · last changed chore(): initial commit 26 days ago source blame history raw
1
#!/usr/bin/env python3
2
"""Check that the VERA tests cite the RTL the emulator claims to implement.
3
4
The VERA conformance tests quote Verilog by file and line. Those citations are
5
only meaningful against one revision, and the revision that matters is the one
6
the emulator reports itself to be: guest software reads VERA_VERSION_MAJOR,
7
MINOR and PATCH back from registers 0x00-0x02 and adapts to them. Whatever
8
firmware any particular physical board carries, an emulator claiming 47.0.2 has
9
to behave like 47.0.2.
10
11
So this fails when src/video.c and tests/fetch_vera_rtl.py stop agreeing.
12
Bumping the emulator's version is legitimate, but it invalidates every cited
13
line number, and that has to be a deliberate step rather than a silent one.
14
15
It does not need the RTL to be present -- it compares two declarations, not the
16
Verilog itself.
17
18
    python tests/check_vera_version.py
19
20
WHAT THIS DOES NOT CHECK, AND WHY IT MATTERS
21
--------------------------------------------
22
The version register is a claim, and the rest of the emulator does not honour
23
it. This is a composite of several revisions rather than any one of them:
24
25
    version register    R47.0.2         video.c
26
    PSG saw/triangle    R48             XOR with ~pulsewidth, vera_psg.c:122-123,
27
                                        backported by #290 on 2024-08-11 -- two
28
                                        months BEFORE the RTL change (a8135f32,
29
                                        2024-10-21) that shipped in R48
30
    PCM AUDIO_CTRL      none            bit 6 restart and bits 7+6 loop match
31
                                        70a03e00, which lived on trunk for five
32
                                        weeks in 2023 and was reverted as an
33
                                        accidental merge
34
    PCM AUDIO_RATE      none            the 256-val fold appears in no revision
35
36
The pattern is that this emulator tracks vera-module trunk and proposals rather
37
than releases, so it can hold behaviour that no released bitstream ever had.
38
39
That makes "base the tests on version X" impossible to satisfy by picking a tag:
40
the emulator would diverge from any single one. Each subsystem records the
41
revision it is actually checked against instead. For PCM the choice is moot --
42
audio_fifo.v, pcm.v and audio.v are byte-identical across v47.0.2 and v48.0.1 --
43
but for PSG it decides the expected waveform, and R48 is what the code
44
implements.
45
46
The tidy end state is to bump this emulator to 48.0.1: PSG already matches it,
47
PCM is unchanged between the two, and the only obstacles are the two PCM
48
behaviours above, which match no revision and are bugs independent of version.
49
"""
50
51
import re
52
import sys
53
from pathlib import Path
54
55
ROOT = Path(__file__).resolve().parent.parent
56
VIDEO_C = ROOT / "src" / "video.c"
57
FETCH = ROOT / "tests" / "fetch_vera_rtl.py"
58
59
# The vera-module tag whose RTL the VERA tests cite, and the emulator version it
60
# corresponds to. Both halves are stated so a mismatch names which side moved.
61
#
62
# One wrinkle, recorded rather than smoothed over: the RTL inside tag v47.0.2
63
# reports 47.0.0 from its own version registers (top.v:191, 199, 207), not
64
# 47.0.2 -- the tag name and the registers disagree in the patch field. v48.0.1
65
# introduced VERSION_MAJOR/MINOR/BUILD defines and is self-consistent. Nothing
66
# in the audio path turns on this, since audio_fifo.v, pcm.v and audio.v are
67
# byte-identical across the two tags, but it does mean that RTL reporting
68
# exactly 47.0.2 does not exist. v47.0.2 is the closest thing to what the
69
# emulator claims.
70
EXPECTED_VERSION = (47, 0, 2)
71
EXPECTED_TAG = "v47.0.2"
72
EXPECTED_COMMIT = "45cc1f053376dae12173ea63612820e4d289c0da"
73
74
75
def emulator_version():
76
    src = VIDEO_C.read_text(encoding="utf-8", errors="replace")
77
    out = []
78
    for part in ("MAJOR", "MINOR", "PATCH"):
79
        m = re.search(rf"^#define\s+VERA_VERSION_{part}\s+(\d+)", src, re.M)
80
        if not m:
81
            print(f"FAIL: VERA_VERSION_{part} not found in {VIDEO_C}")
82
            return None
83
        out.append(int(m.group(1)))
84
    return tuple(out)
85
86
87
def pinned_commit():
88
    src = FETCH.read_text(encoding="utf-8", errors="replace")
89
    m = re.search(r'^COMMIT\s*=\s*"([0-9a-f]{40})"', src, re.M)
90
    if not m:
91
        print(f"FAIL: no COMMIT pin found in {FETCH}")
92
        return None
93
    return m.group(1)
94
95
96
def main():
97
    version = emulator_version()
98
    commit = pinned_commit()
99
    if version is None or commit is None:
100
        return 1
101
102
    ok = True
103
104
    if version != EXPECTED_VERSION:
105
        got = ".".join(str(n) for n in version)
106
        want = ".".join(str(n) for n in EXPECTED_VERSION)
107
        print(f"FAIL: emulator reports VERA {got}, tests are written against {want}")
108
        print("      The cited RTL line numbers no longer describe what this")
109
        print("      emulator claims to be. Re-point tests/fetch_vera_rtl.py at")
110
        print(f"      the matching vera-module tag, re-verify every citation in")
111
        print("      tests/test_vera_pcm.c, then update EXPECTED_* here.")
112
        ok = False
113
114
    if commit != EXPECTED_COMMIT:
115
        print(f"FAIL: fetch_vera_rtl.py pins {commit[:8]}, expected {EXPECTED_COMMIT[:8]} ({EXPECTED_TAG})")
116
        print("      Re-verify the cited line numbers against the new revision")
117
        print("      before updating EXPECTED_COMMIT.")
118
        ok = False
119
120
    if ok:
121
        v = ".".join(str(n) for n in version)
122
        print(f"ok  : emulator reports VERA {v}; oracle pinned to {EXPECTED_TAG}")
123
    return 0 if ok else 1
124
125
126
if __name__ == "__main__":
127
    sys.exit(main())