ci: cross-check RTL vs GVSoC cycle counts per tile#40
Draft
diaconuccalin wants to merge 6 commits into
Draft
Conversation
Add a CI gate that compares per-tile cycle counts between the RTL
(Modelsim) and GVSoC simulators for the same test binary, failing if any
tile diverges by more than 10%.
The same binary runs on both sims, so instrumentation is platform-agnostic
and read out differently per platform:
- RTL: sentinel_start/end are detected by the MAGIA testbench
(PROFILE_SENTINEL, requires build_mode=profile), which prints per-tile
"(<N> clock cycles)".
- GVSoC: xperf_end prints the mcycle CSR delta as
"[XPERF] mhartid <id> CYCLES <n>".
Changes:
- xperf_start/xperf_end helper (magia_v1 + v2 performance_utils.h),
gated by the PROFILE_XPERF flag (default off; threaded through Makefile
and both CMakeLists like the existing PROFILE_* flags). When off both
calls compile to nothing, leaving default builds unchanged.
- One xperf pair around the work region of the 14 RTL-CI tests.
- scripts/ci/compare_cycles.py: per-tile ±10% comparison, hard fail.
- .gitlab-ci.yml: build RTL with build_mode=profile, build tests with
profile_xperf=1, namespace sim logs (.rtl.log/.gvsoc.log), add
compare_tiles_4 / compare_tiles_1 stages for the 1x1 and 4x4 configs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
xperf_end() uses get_hartid()/printf(), which were only available via tile.h's include order. Drivers (e.g. idma32.c) pull performance_utils.h through idma_isa_utils.h without magia_utils.h first, so with profile_xperf=1 get_hartid() was implicitly declared and then conflicted with its real definition, breaking the build. Include magia_utils.h directly in performance_utils.h (v1 and v2); it provides get_hartid() and transitively printf(), and nothing in that chain includes performance_utils.h, so there is no include cycle. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- github-ci.yml: upload the fetched gitlab-logs/ dir (full job traces plus the unzipped test_*.rtl.log / test_*.gvsoc.log artifacts) as a downloadable GitHub Actions artifact, and print the .log tails inline alongside traces. - Reduce the RTL-vs-GVSoC cycle match tolerance from 10% to 5% (.gitlab-ci.yml COMPARE_TOL and compare_cycles.py --tol default). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The MAGIA testbench sentinel monitor (magia_vip.sv) inspects the WB stage every cycle, so a sentinel instruction held in WB across a short pipeline stall (a following CSR read / MMIO store / fsync) was counted more than once. That produced spurious "sentinel end without corresponding start" ** Error messages, inflating Modelsim's "Errors: N" summary, which sim_ret_errors.sh then read as a test failure (test_gemv, test_mm_is_2, test_mm_ws_2) even though every tile reported 0 functional errors. Pad each sentinel in xperf_start/xperf_end with 8 NOPs so it retires from WB before any stalling instruction follows it. The padding sits outside the GVSoC measurement points and adds a negligible, constant offset to the RTL window (~16 cycles on ~11k), well within the 5% tolerance. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a CI gate that compares per-tile cycle counts between the RTL (Modelsim) and GVSoC simulators for the same test binary, failing if any tile diverges by more than ±10%. Runs on the 14 RTL-CI tests for the 1×1 and 4×4 tile configs.
How
The same binary runs on both sims, so the instrumentation is platform-agnostic and read out differently per platform:
sentinel_start()/sentinel_end()are no-ops on the core but detected by the MAGIA testbench (magia_vip.sv,PROFILE_SENTINEL, requiresbuild_mode=profile), which prints per-tile(<N> clock cycles).xperf_end()prints the mcycle CSR delta as[XPERF] mhartid <id> CYCLES <n>(perf_get_cycles()does not work on RTL).Both lines are keyed by
mhartid→ per-tile comparison.Changes
xperf_start/xperf_endhelper (targets/magia_v{1,2}/include/utils/performance_utils.h), gated by the newPROFILE_XPERFflag (default off; threaded throughMakefileand bothCMakeLists.txtlike the existingPROFILE_*flags). When off, both calls compile to nothing, so default builds (regression, gvtest, other RTL tests) are byte-identical and emit no[XPERF]lines.xperfpair around the work region of the 14 tests.scripts/ci/compare_cycles.py— per-tile ±10% comparison, hard fail..gitlab-ci.yml— build RTL withbuild_mode=profile, build tests withprofile_xperf=1, namespace sim logs (.rtl.log/.gvsoc.log), addcompare_tiles_4/compare_tiles_1stages.Granularity
v1 is one region per test (one cycle number per tile). The path to ordered multi-segment profiling is documented but not implemented (the RTL testbench only decodes the generic sentinel pair, not the per-category sentinels).
To watch on first run
build_mode=profile+fast_sim=1coexistence, and the testbench(clock cycles)lines landing in captured stdout.test_helloworld's tiny cycle count may be noisy at ±10% — easy to widen or drop.🤖 Generated with Claude Code