RogueTcp Stream/Memory/SideBand: GHDL VHPIDIRECT cosim + cocotb CI coverage#1450
Open
ruck314 wants to merge 16 commits into
Open
RogueTcp Stream/Memory/SideBand: GHDL VHPIDIRECT cosim + cocotb CI coverage#1450ruck314 wants to merge 16 commits into
ruck314 wants to merge 16 commits into
Conversation
ruck314
force-pushed
the
ci-RogueTcpMemoryWrap-RogueTcpStreamWrap
branch
from
July 5, 2026 23:16
7a1feed to
b996467
Compare
There was a problem hiding this comment.
Pull request overview
This PR brings the Rogue TCP sim-link stream, memory, and sideband simulation models under GHDL using VHPIDIRECT (while keeping the existing VCS/VHPI backend), adds shared simulator-agnostic C cores, and introduces cocotb/valgrind-driven CI coverage to prevent regressions.
Changes:
- Reorganize
axi/simlinkintoshared/cores plus thinvcs/(VHPI) andghdl/(VHPIDIRECT) backends. - Add always-run selection for
tests/axi/simlink/in the selective test resolver, plus new cocotb round-trip/smoke tests and a pyzmq peer. - Wire CI dependencies (libzmq, valgrind, pyzmq) and add flat VHDL wrappers for cocotbext.axi.
Reviewed changes
Copilot reviewed 43 out of 49 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/common/test_dep_map.py | Adds unit test ensuring simlink tests are always-run in selective resolution. |
| tests/common/dep_map.py | Adds directory-scoped always-run rule for tests/axi/simlink/. |
| tests/axi/simlink/uninit_read_recv_harness.c | Standalone harness to reproduce/guard uninitialized read bug under valgrind. |
| tests/axi/simlink/test_RogueTcpStreamWrap.py | Adds cocotb round-trip + sparse-tkeep regression for stream flat wrapper. |
| tests/axi/simlink/test_RogueTcpStream.py | Adds GHDL/VHPIDIRECT elaborate/bind smoke test for stream model. |
| tests/axi/simlink/test_RogueTcpMemoryWrap.py | Adds cocotb round-trip test for memory flat wrapper + valgrind repro. |
| tests/axi/simlink/test_RogueTcpMemory.py | Adds GHDL/VHPIDIRECT elaborate/bind smoke test for memory model. |
| tests/axi/simlink/test_RogueSideBandWrap.py | Adds cocotb round-trip test for sideband flat wrapper. |
| tests/axi/simlink/test_RogueSideBand.py | Adds GHDL/VHPIDIRECT elaborate/bind smoke test for sideband model. |
| tests/axi/simlink/simlink_test_utils.py | Adds helper to build/stage VHPIDIRECT .so and ensure LD_LIBRARY_PATH works in CI. |
| tests/axi/simlink/rogue_tcp_peer.py | Adds separate-process pyzmq peer implementing the simlink wire protocols for tests. |
| tests/axi/simlink/init.py | Marks simlink tests as a Python package. |
| ruckus.tcl | Bumps required ruckus submodule version. |
| pip_requirements.txt | Adds pyzmq for the new peer/tests. |
| conda.yml | Adds pyzmq to conda environment. |
| axi/simlink/wrappers/RogueTcpStreamWrapFlatWrapper.vhd | Adds cocotb-facing flat AXI-stream wrapper for surf.RogueTcpStreamWrap. |
| axi/simlink/wrappers/RogueTcpMemoryWrapFlatWrapper.vhd | Adds cocotb-facing flat AXI-Lite wrapper for surf.RogueTcpMemoryWrap. |
| axi/simlink/wrappers/RogueSideBandWrapFlatWrapper.vhd | Adds cocotb-facing flat wrapper for surf.RogueSideBandWrap. |
| axi/simlink/vcs/VhpiGeneric.h | Moves/hosts VHPI generic interface header under vcs/. |
| axi/simlink/vcs/VhpiGeneric.c | Moves/hosts VHPI generic interface implementation under vcs/. |
| axi/simlink/vcs/RogueTcpStream.vhd | Moves VHPI-bound VHDL entity into vcs/. |
| axi/simlink/vcs/RogueTcpStream.h | Updates VHPI backend header to use shared core via snapshot seam. |
| axi/simlink/vcs/RogueTcpStream.c | New thin VHPI backend linking shared stream core. |
| axi/simlink/vcs/RogueTcpMemory.vhd | Moves VHPI-bound VHDL entity into vcs/. |
| axi/simlink/vcs/RogueTcpMemory.h | Updates VHPI backend header to use shared core via snapshot seam. |
| axi/simlink/vcs/RogueTcpMemory.c | New thin VHPI backend linking shared memory core. |
| axi/simlink/vcs/RogueSideBand.vhd | Moves VHPI-bound VHDL entity into vcs/. |
| axi/simlink/vcs/RogueSideBand.h | Updates VHPI backend header to use shared core via snapshot seam. |
| axi/simlink/vcs/RogueSideBand.c | New thin VHPI backend linking shared sideband core. |
| axi/simlink/vcs/Makefile | Updates includes to build against shared/ core headers. |
| axi/simlink/src/RogueTcpStream.c | Removed (logic moved into shared/ + thin vcs/ backend). |
| axi/simlink/src/RogueTcpMemory.c | Removed (logic moved into shared/ + thin vcs/ backend). |
| axi/simlink/src/RogueSideBand.c | Removed (logic moved into shared/ + thin vcs/ backend). |
| axi/simlink/shared/RogueTcpStreamCore.h | New shared stream transport+FSM core used by both backends. |
| axi/simlink/shared/RogueTcpMemoryCore.h | New shared memory transport+FSM core used by both backends. |
| axi/simlink/shared/RogueSideBandCore.h | New shared sideband transport+FSM core used by both backends. |
| axi/simlink/ruckus.tcl | Switches sim-only VHPI sources from sim/ to vcs/ when not using GHDL. |
| axi/simlink/ghdl/RogueTcpStream.vhd | Adds GHDL VHPIDIRECT binding for stream model. |
| axi/simlink/ghdl/RogueTcpStream.h | Adds GHDL backend header/shims for stream model. |
| axi/simlink/ghdl/RogueTcpStream.c | Adds GHDL VHPIDIRECT backend implementation for stream model. |
| axi/simlink/ghdl/RogueTcpMemory.vhd | Adds GHDL VHPIDIRECT binding for memory model. |
| axi/simlink/ghdl/RogueTcpMemory.h | Adds GHDL backend header/shims for memory model. |
| axi/simlink/ghdl/RogueTcpMemory.c | Adds GHDL VHPIDIRECT backend implementation for memory model. |
| axi/simlink/ghdl/RogueSideBand.vhd | Adds GHDL VHPIDIRECT binding for sideband model. |
| axi/simlink/ghdl/RogueSideBand.h | Adds GHDL backend header/shims for sideband model. |
| axi/simlink/ghdl/RogueSideBand.c | Adds GHDL VHPIDIRECT backend implementation for sideband model. |
| axi/simlink/ghdl/Makefile | Adds GHDL-only Makefile to build VHPIDIRECT .so modules. |
| .gitignore | Broadens ignore pattern to include sim_build* dirs. |
| .github/workflows/surf_ci.yml | Adds CI deps (libzmq, valgrind) and runs simlink tests under xdist. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ruck314
force-pushed
the
ci-RogueTcpMemoryWrap-RogueTcpStreamWrap
branch
2 times, most recently
from
July 6, 2026 00:21
0d83efe to
1e19314
Compare
ruck314
marked this pull request as ready for review
July 6, 2026 00:35
ruck314
force-pushed
the
ci-RogueTcpMemoryWrap-RogueTcpStreamWrap
branch
from
July 6, 2026 17:33
1e19314 to
58f111b
Compare
ruck314
changed the base branch from
ci-test-cherry-pick-using-GHDL-cf-file
to
pre-release
July 6, 2026 17:34
ruck314
force-pushed
the
ci-RogueTcpMemoryWrap-RogueTcpStreamWrap
branch
3 times, most recently
from
July 6, 2026 19:42
2411d68 to
1fa1284
Compare
Reorganize the Rogue simlink sources to support multiple simulator backends. The VCS/Vivado VHPI-specific C shims, headers, Makefile, and VHDL move from src/ and sim/ into vcs/, while the backend-agnostic protocol logic (ZMQ peering, memory/stream/side-band framing) is lifted into shared/ core headers (RogueTcpMemoryCore.h, RogueTcpStreamCore.h, RogueSideBandCore.h) that any backend can include. Update axi/simlink/ruckus.tcl to reference the new paths.
Add a GHDL VHPIDIRECT backend for the Rogue simlink modules alongside the existing VCS/Vivado path. New ghdl/ C shims bind the shared core to GHDL's VHPIDIRECT ABI, and the paired VHDL exposes foreign subprograms for RogueTcpMemory, RogueTcpStream, and RogueSideBand. Add flat-port wrappers under wrappers/ (RogueTcpMemoryWrapFlatWrapper, RogueTcpStreamWrapFlatWrapper, RogueSideBandWrapFlatWrapper) so records are flattened to std_logic_vector for cocotb DUT access. Fail fast if a VHPIDIRECT backend is instantiated more than once, since the C core keeps per-module global state that a second instance would corrupt.
Add a cocotb test suite for the GHDL VHPIDIRECT simlink backend covering RogueTcpMemory, RogueTcpStream, and RogueSideBand plus their flat Wrap variants. rogue_tcp_peer.py provides a Rogue-TCP ZMQ peer that drives the DUT over the same wire protocol Rogue uses, and simlink_test_utils.py builds the per-test .so, serializing that build under a file lock so pytest-xdist workers do not race.
Add pyzmq to conda.yml and pip_requirements.txt for the Rogue-TCP ZMQ peer, add libzmq3-dev and valgrind to the regression job's apt install so the Rogue-TCP VHPIDIRECT shims link and test_RogueTcpMemoryWrap.py can run under valgrind, and widen the .gitignore sim_build rule to sim_build* for the generated sim build artifacts.
Stop loading the simulation-only wrappers/ directory from protocols/jesd204b/ruckus.tcl so it stays out of the synthesized surf library. The flattened surf library imported for the cocotb regression then no longer contains the wrapper entities and GHDL fails to elaborate them (jesdrxlanewrapper, jesd204brxwrapper, jesdscramblerwrapper, jesdtxlanewrapper, jesd204btxwrapper, jesd204bloopbackwrapper). Add a jesd_wrapper_sources() helper to jesd204b_test_utils.py and pass each bench its wrapper through run_surf_vhdl_test(extra_vhdl_sources=...), so the wrapper compiles on top of the already-imported RTL. Keeps the simulation-only wrappers out of the synthesized library while restoring test coverage.
ruck314
force-pushed
the
ci-RogueTcpMemoryWrap-RogueTcpStreamWrap
branch
from
July 8, 2026 18:45
2c97b87 to
a1e7ee7
Compare
bengineerd
reviewed
Jul 15, 2026
bengineerd
left a comment
Contributor
There was a problem hiding this comment.
Review found three areas to address: fixed-buffer bounds safety, stale incremental GHDL builds, and regression-environment portability. Details are inline.
Guard both directions of the shared AXI-Stream core against writing past the fixed MAX_FRAME buffers. RogueTcpStreamRecv() copied the peer-declared size of the fourth ZMQ frame straight into obData[MAX_FRAME]; reject the frame first. The inbound RogueTcpStreamStep() loop grew ibSize per kept lane with no cap, so a frame that never asserted tLast overran ibData[MAX_FRAME]; guard ibSize before each byte write.
RogueTcpMemoryRecv() trusted the peer-declared size: a write copied it into the fixed data[MAX_DATA] buffer, and the AXI-Lite FSM advances curr four bytes per beat and completes only when curr == size. An oversized size overran data[], and a non-word-sized size made curr step past size so the transaction never terminated. Reject size > MAX_DATA or not a multiple of four before the size is used.
The GHDL Makefile pattern rule tracked only the .c file, so editing a shared shared/RogueTcp*Core.h (or a local RogueTcp*.h / RogueVhpiDirect.h) left the previously built .so in place and pytest loaded the stale library, producing false-green local runs. Emit per-module dependency files with -MMD -MP and -include them so any compiled-through header is a prerequisite.
test_RogueTcpMemory_uninitialized_read invokes valgrind unconditionally, which errors on macOS and on a clean conda env without valgrind. Skip it unless running on Linux with valgrind on PATH. Add zeromq and pkg-config to conda.yml so the simlink .so actually builds in the conda environment (the apt step only covers the Ubuntu CI runner).
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.
Description
Adds GHDL/VHPIDIRECT co-simulation backends for the Rogue TCP Stream, Memory, and SideBand models with cocotb regression coverage in CI. The simlink tree is organized into
vcs/,ghdl/, and shared simulator-independent C cores so GHDL and VCS use the same ZeroMQ wire protocols and model state machines.Each elaborated GHDL model owns independent native state through an explicit positive integer handle, including model creation, lookup, port reservation, destroy, and process-exit cleanup. This supports multi-link Stream users and concurrent Stream, Memory, and SideBand instances while preserving the existing public VHDL interfaces.
The change also fixes three shared C-model defects found during regression development: an uninitialized Memory read-frame copy, sparse Stream
tKeepbyte over-counting, and mismatched Memory socket NULL guards.Details
RogueTcpStreamCore.h,RogueTcpMemoryCore.h, andRogueSideBandCore.has the shared model implementation.The shared simulator-thread transport policy is intentionally unchanged: receives poll nonblocking, sends remain synchronous, and the peer must be connected and draining before outbound HDL traffic. No-peer, saturation, send-timeout, linger, retry-queue, or worker-thread changes belong in a later cross-backend hardening pull request covering VCS, GHDL, and xsim together.
Validation completed on implementation head
989731d754e729d3866308e7529c0c2842a73695; GitHub Actions run 29461564882 passed lint, documentation, and regression checks. Linux reported 813 passed and 21 skipped, including active multi-instance traffic, lifecycle Valgrind, duplicate-port, and invalid-handle tests. VCS execution was not available locally, but the VCS source path and shared-core consumers were reviewed and the established wire formats and transport policy were preserved.Related