Skip to content

Assignment Propagation#271

Merged
ekiwi merged 12 commits into
mainfrom
propagaton
Jul 8, 2026
Merged

Assignment Propagation#271
ekiwi merged 12 commits into
mainfrom
propagaton

Conversation

@Nikil-Shyamsunder

@Nikil-Shyamsunder Nikil-Shyamsunder commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

This PR changes the graph IR assignment representation away from nested ITEs and adds a reaching-definitions pass that gives us info so we can propagates assignment forward so every reachable node has a total assignment for every DUT input port.

The main interesting things:

Assignment Representation: (see #268 for details)

  • Op::Assign now stores an Assignment summary: Assignment { dont_care: ExprRef, concretes: Vec<(ExprRef, ExprRef)> }

  • edge_contract.rs implements ordered and unordered assignment merging over this representation.

    • Ordered merge is used for sequential/intra-transaction merging, where late assignments win.
    • Unordered merge is used for parallel/graft/determinize-style merging, where concrete assignments from one side are preferred over DontCare from the
      other side.
  • The graph interpreter and graphviz output were updated to understand the new assignment summaries.

    • Codegen/evaluation checks dont_care first, then concrete branches.
    • Graphviz prints assignments like X if g; value if h.
    • There is an internal assertion if an assignment reaches no DontCare or concrete branch.

Reaching Definitions analysis:

  • reaching_defs.rs adds reaching-definitions analysis over the graph.
    • It computes out_defs per node
    • The analysis restricts incoming assignments by transition guards before merging.
    • Incoming definitions are merged with unordered semantics.
    • If a join produces multiple possible incoming outcomes for the same port, that port is marked as an incoming conflict.
    • A node-local assignment kills the incoming conflict for that port.
    • If any incoming conflicts remain after the transfer function for a node, we fail fast.

Assignment propagation:

  • propagate_assigns.rs uses the reaching definitions to rewrite reachable nodes so that every DUT input port has a total assignment at every node.
    • It removes old input assignments from each reachable node.
    • It inserts the reaching out_def assignment for every input port.
    • This pass assumes the reaching-def analysis has already rejected unresolved
      incoming conflicts.

Default DontCare on Entry, Assign DontCare on exit:

  • lowering.rs now emits explicit default DontCare assignments on the entry node.
    • The fragment exit also assigns every DUT input to DontCare, i.e. transactions relinquish their ports on exit.

Tests

This PR updates the unit tests around assignment merging and lowering:

  • edge-contract tests now construct guarded assignments by putting guards inside Assignment, not on the Action.
  • unordered merge tests now expect effective concrete guards.
  • lowering tests now account for the explicit fragment-entry DontCare node and exit relinquish assignments.
  • TODO: there are some Xfail tests due to waveform diffing expressivity.

@Nikil-Shyamsunder Nikil-Shyamsunder force-pushed the propagaton branch 3 times, most recently from f22a2b1 to 10035d0 Compare July 8, 2026 03:14
Comment thread protocols/src/ir/lowering.rs
@Nikil-Shyamsunder Nikil-Shyamsunder marked this pull request as ready for review July 8, 2026 15:21
@ekiwi

ekiwi commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

@Nikil-Shyamsunder : I just rebased this on main. I will merge as soon as CI passes.

@ekiwi ekiwi merged commit 72d1019 into main Jul 8, 2026
24 of 27 checks passed
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.

2 participants