Ugn grooming embedded#1324
Draft
lmbollen wants to merge 21 commits into
Draft
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
lmbollen
force-pushed
the
lucas/ugn-grooming-embedded
branch
from
June 4, 2026 15:43
a938ba6 to
989e3d5
Compare
Increase MU processing element instruction and data memory from 16KB to 160KB (10 RAMB18E2 blocks each) to accommodate the larger smoltcp-demo firmware binary. Refactor the RingBuffer simulation test infrastructure to load firmware binaries by name instead of building PeConfig from Haskell. Add simSmolTcp for simulating the smoltcp ring buffer test. Support multiple TX/RX ring buffer pairs in the DUT circuit. Remove IO from simResultRingBuffer return type.
Update all internal doc references to use the new hyphenated ring-buffer naming convention.
Replace the pinned git smoltcp 0.11 dependency in bittide-hal with crates.io smoltcp 0.12. Add the medium-ip feature needed for point-to-point links. Remove workspace lints inherited section. Fix ring_buffer_test to use the renamed device instance fields (transmit_ring_buffer_0, receive_ring_buffer_0) after the ring buffer HAL was updated to support multiple ring buffers per device.
Move MAC address utilities from smoltcp.rs into smoltcp/mac.rs and convert the smoltcp module from a single file to a directory module. Update smoltcp_client to use the new import path. Also update smoltcp_client to remove workspace lints, add medium-ip feature, and fix format string and mutability warnings.
Log state changes in the link startup state machine to aid debugging link bring-up issues on hardware.
Add modules for TCP-over-ring-buffer communication between nodes: - net_state: UGN graph types (UgnEdge, UgnReport) for collecting network state across nodes - smoltcp/ring_buffer: smoltcp Device implementation over aligned ring buffers with CRC integrity and sequence numbers - smoltcp/link_protocol: wire format types for inter-node commands and UGN edge data - smoltcp/link_interface: high-level LinkInterface combining smoltcp TCP with ring buffer transport, providing typed send/recv over point-to-point links Add crc and zerocopy dependencies. Enable generic_const_exprs feature gate. Remove workspace lints inherited section. Add medium-ip feature to smoltcp.
Add three new firmware crates: - smoltcp-demo: HITL demo for soft UGN collection over TCP links, with ring buffer alignment, DNA exchange, and UGN report aggregation via a manager/subordinate protocol - ring_buffer_smoltcp_test: simulation test for TCP over ring buffers - tcp_simultaneous_open_test: simulation test for TCP simultaneous open (both sides connect at the same time)
One demo needs significantly larger memories, this way we dont have to do that for each demo
A small directed, weighted graph backed by a Data.Map adjacency structure, with the Bellman-Ford shortest-path / negative-cycle machinery (potentials, relabel, negativeCycle, cycleSum). Node and weight types are generic. This is the reusable foundation for UGN grooming: deciding whether a set of UGNs is physically allowed reduces to "no negative cycle". Kept standalone (no UGN specifics) so it can be tested and reused independently.
UGNs are signed per-link clock/frame offsets (edge weights). They are physically
allowed iff the sum around every directed cycle is nonnegative, and one boot can be
relabeled onto another iff a difference-constraint system is feasible. Both reduce to
the negative-cycle / potential machinery from Bittide.Graph.Weighted.
Provides isAllowed and groomCorrection (Infeasible | Feasible{correction, frames}),
using Integer weights to avoid overflow during relaxation. Pure and demo-agnostic.
A small Wishbone peripheral with one management-unit-writable register (release_cycle, default maxBound, with a description) that takes a local counter and holds its output reset asserted until localCounter > release_cycle, then deasserts (monotonic counter, so it stays deasserted). This is how the large boot-time counter offset (the grooming relabel q, far too big for the depth-bounded elastic buffer) is realised: gating a domain's reset on a chosen cycle sets that domain's counter origin. Generic over the Wishbone width; unit test verifies the reset deasserts exactly at the written cycle.
A small Wishbone scratch peripheral with two read/write registers: a vector of n signed per-link corrections (init 0) and a valid flag (init False). The host computes the per-link grooming frame corrections and writes them here over GDB; the management-unit CPU polls valid, reads the corrections and applies them to its elastic buffers. Plain bus-accessible scratch (no fabric writes), mirroring the CaptureUgn idiom.
… the user core
Add both host-facing grooming peripherals to the generic management unit
(NmuInternalBusses 3 -> 5):
- UgnCorrections: the host writes per-link frame corrections for the MU CPU to
apply.
- TimedReset: the management unit chooses the local-counter cycle at which the
application leaves reset (the boot-offset relabel). It lives here, in the layer
around the user core, and exposes an `appReset` output.
`core` routes `appReset` into the user core via a new `UserCoreCircuit` argument. The
wire demo's user core uses it as the relabeled time base: an application counter that
starts at release and drives the programmable mux (UserCoreBusses 3 -> 2, since the
timed reset no longer sits on a user-core bus). The application counter stays in the
user core; the soft-UGN user core ignores the reset.
Host-side helpers for the grooming flow, placed beside the existing HITL utilities: GDB-based component HAL accessors (readCurrentTime, writeReleaseCycle, writeCorrections, readHardwareUgns, readAppCounter) in Utils.Gdb, and the UgnEdge conversions (ugnEdges, hardwareUgnEdges) in Utils.Ugn.
After printing the captured UGNs, the management unit polls the UgnCorrections peripheral's valid flag, then applies each link's frame correction to its elastic buffer as a single atomic wishbone write with hardware ack (rather than one frame at a time). A per-frame loop is vulnerable to concurrent Callisto adjustments between iterations, which shrink the net data_count change; a single write limits the Callisto race window to at most one adjustment, keeping the error to ±1 frame. It self-reports a success line the host waits on. The firmware half of the grooming apply path; the corrections values and the reset-release timing are computed and written by the host.
…rdware Diagnostic instrumentation to pin down why the canonical-gauge grooming breaks the XOR chain partway (nodes 0-2 pass, 3-7 fail) despite the schedule math being equivalent to main's proven generateSchedule and the frame path being exercised by an earlier green run. - UserCore: expose the application counter via a read-only Wishbone register (new AppCounterReadback device, UserCoreBusses 2 -> 3). With the app running, localCounter - app_counter == tReset for a node iff its timed-reset relabel released at the intended (relabeled) cycle. - Driver: after the app runs, read each node's app_counter + localCounter and print loc-app vs tReset, so a divergence pinpoints which node's reset did not land. This is instrumentation, not the fix; it isolates whether the failure is the Bellman-Ford reset relabel not landing on-device vs the frame corrections.
…golden UGNs for FifoSize=6 midpoint
Stacking the UGN-grooming work on top of the ring-buffer/smoltcp branch
surfaces two integration points in the async-comms demo, which the
grooming branch never saw:
* grooming added an application-reset argument to 'UserCoreCircuit';
forward it (unused) in the demo's 'mkUserCore'.
* the demo's driver still used 'Utils.Picocom'; main has since renamed
it to 'Utils.Serial', so move to 'initSerial' (matching the other
demo drivers).
lmbollen
force-pushed
the
lucas/ugn-grooming-embedded
branch
from
June 15, 2026 14:17
a080ba8 to
17a2c8c
Compare
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 (what did you do)
Why (context, issues, etc.)
Dear reviewer (anything you'd like the reviewer to pay close attention to?)
AI disclaimer (heads-up for more than inline autocomplete)
TODO
Cross-outany that do not applydocs/