Skip to content

feat(preview): annotate multi-bit pins with [N] width suffix - #68

Merged
jeffersonmourak merged 1 commit into
mainfrom
s11.1-preview-width-annotation
May 24, 2026
Merged

feat(preview): annotate multi-bit pins with [N] width suffix#68
jeffersonmourak merged 1 commit into
mainfrom
s11.1-preview-width-annotation

Conversation

@jeffersonmourak

Copy link
Copy Markdown
Owner

Summary

Pin labels in --preview now render as name[N] for width > 1 and stay bare for width 1, so existing scalar preview goldens are unchanged. The annotation flows from the topology's per-component width byte through VirtualNodePlacedComponent into the render pass.

Pin Before After
input a (width 1) │ a │ │ a │
input[4] a │ a │ (no annotation) │ a[4] │
output[8] r │ r │ │ r[8] │

Layout

pinSize now takes the signal width and adds widthAnnotationLen(width) to the padded box width (3 chars for single-digit widths, 4 for two-digit). The mixed-width fixture demonstrates scalar and multi-bit pins coexisting without truncation.

Subtle correctness fix

The Canvas.setCell stores slice pointers, not copies. My first cut composed the label in a stack-local [128]u8 = undefined buffer inside drawInputPin, which produced visibly garbled output (▢1+k instead of a[4]) once the stack frame popped — the canvas held dangling pointers.

Fix: compose the label in arena-owned memory at placement time. PlacedComponent gained a display_label: []const u8 = "" field; pin renderers fall back to placed.name when display_label is empty, so the dozens of existing test fixtures that build PlacedComponent literals don't need updating.

Test plan

  • Four new preview fixtures cover the requested cases: multi-bit input pin label, multi-bit output pin label, multi-bit AND gate with width-4 inputs/output, mixed scalar + multi-bit pins.
  • Existing scalar preview goldens are byte-identical (the bare-label path is unchanged).
  • zig build test green from a clean cache.
  • zig build bench reports golden matches on all 56 fixtures.

S11.2 (LED rendering for width >1 + --expand-display flag) is the matching follow-up that stacks on this PR.

Context: DOCS/plan-multi-bit-language.md §"Stage 11".

Closes #52

Pin labels in `--preview` now render as `name[N]` for width > 1 and
stay bare for width 1, so existing scalar preview goldens are
unchanged. The annotation flows from the topology's per-component
width byte through VirtualNode → PlacedComponent into the render
pass.

Layout accounts for the wider label: pinSize takes the signal width
and adds the digit count plus brackets to the padded box width. A
mixed-width fixture confirms scalar and multi-bit pins coexist
without truncation or column-width contamination.

One subtle correctness fix along the way: the canvas stores slice
pointers from setCell (not copies), so the label string must outlive
the canvas. Composing the label in arena-owned memory at placement
time guarantees that lifetime — an earlier attempt that used a
stack-local buffer inside drawInputPin produced visibly garbled
output once the stack frame popped. PlacedComponent now carries a
`display_label` field with the arena-owned string; tests that build
PlacedComponent literals fall back to the raw name when
display_label is empty.

Engine bench reports golden matches on all 56 fixtures; preview is a
render-time concern that never touches the engine.
@jeffersonmourak
jeffersonmourak merged commit 3648664 into main May 24, 2026
3 checks passed
@jeffersonmourak
jeffersonmourak deleted the s11.1-preview-width-annotation branch May 24, 2026 21:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

S11.1: Multi-bit signal width annotation in preview

1 participant