Skip to content

multilayer_sequencer: level-triggered prefetch handshake cannot distinguish "done already" from "done still" #2342

Description

@gHashTag

Split out of #1985, which reported two independent defects in two different modules. The
first — weight_prefetch_ctrl never retiring prefetch_done — is fixed on master by #2340.
This issue carries the second half, which lives in a different file and is a different change.

The defect

multilayer_sequencer (bootstrap/src/bitnet_pipeline.rs) waits on prefetch_done with a
level test:

PREFETCH: begin start_prefetch<=1'b1; state<=WAIT_PF; end
WAIT_PF: if(prefetch_done) state<=RUN;

A level-triggered handshake cannot distinguish "done already" from "done still". WAIT_PF
samples the flag in the same cycle it holds start_prefetch high, so its correctness depends
entirely on the producer having lowered the flag by then.

Status after #2340

#2340 makes weight_prefetch_ctrl retire prefetch_done on entry to IDLE, so the flag is
genuinely a one-cycle pulse. Measured end-to-end with the real sequencer and the real
controller, two layers:

controller overlap_cycles layer_start_during_prefetch
before #2340 1 1
after #2340 0 0

So the observable overlap is closed today. What is not closed is the coupling: the
sequencer is correct only because the producer happens to clear the flag in time. Any future
producer that holds prefetch_done for more than the idle gap — or any added latency between
PREFETCH and WAIT_PF — reintroduces the fall-through silently, with no assertion to catch it.

Suggested shape

#1985 proposed an explicit request/acknowledge, which makes the handshake edge-insensitive
rather than relying on producer timing:

if (!prefetch_done) pf_ack <= 1'b1;      // observe it low = acknowledged
if (pf_ack && prefetch_done) begin ... end

Why this is filed rather than bundled

It is a different module from the one #2340 touches, and #2340's diff was kept to the defect
it proved. Worth noting for whoever picks this up: no workflow runs cargo test -p t27c
(corpus-ratchet.yml records the step being removed by #2292 after going red on master), so
a guard added here will not be executed by any required check as things stand.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions