pub enum EventTerm {
Edge {
cell: StateCellId,
edge: EdgeKind,
iff: Option<PredicateFn>,
},
ImplicitAny(Vec<StateCellId>),
Select {
cell: StateCellId,
edge: EdgeKind,
lsb: u32,
width: u32,
},
NamedEventTrigger(StateCellId),
Repeat {
count: u64,
inner: Box<EventTerm>,
},
}Expand description
One @(...)/wait(...) disjunct (scheduler.md §4/§5; ledger SC-048..SC-051,
SC-065).
Variants§
Edge
ImplicitAny(Vec<StateCellId>)
Select
A wait on a bit/part select of one cell (@(v[3]), @(posedge v[5:4]), LRM 9.4.2): it fires on an update that changed bits [lsb, lsb + width) of cell (any change when edge is None, else the
transition of bit lsb classified as edge). The update is judged on
its own old/new words (ChangeDelta), so a bit that is set and cleared
again by two updates in one time step wakes the waiter once per
update, exactly as the LRM’s update events do (4.9.4).
NamedEventTrigger(StateCellId)
Also the resolution for BlockEventListControl (@(block. triggered)), SC-054’s own “kept as a hook-only EventTerm mapping
in v1” acceptance, resolved here rather than by adding a 5th
variant: @(block.triggered) needs no new EventTerm shape at
all – codegen reserves one synthetic StateCellId per named
statement block and fires it (through the same TimerAction:: TriggerEvent/direct notify_change fan-out an ordinary ->/->>
trigger already uses, sched::wheel’s own SC-069 doc comment)
exactly when that block completes – i.e. .triggered is modeled as
an ordinary named event whose trigger site is block-exit instead of
an explicit -> statement. NamedEventTrigger’s own
scheduler-side consumption (installing an any-change dynamic entry
keyed by the cell, waking every waiter on a real fire) is already
real and tested (Task 5, sched::sensitivity::tests:: named_event_trigger_term_installs_an_any_change_dynamic_entry) –
what remains for @(block.triggered)
specifically is purely whether codegen (B-process, out of this
track’s ownership) actually emits the block-exit trigger call; this
scheduler-side half never hits a silent mis-simulation regardless
(SC-054’s own negative acceptance clause), since an unfired trigger
cell simply never wakes anyone – observably a hang/timeout, never a
wrong value.
Repeat
repeat(count)@(...) (mirrors slang’s RepeatedEventControl{expr, event}; ledger SC-052). SensitivityTable::install_term installs
only inner’s own edge at this term’s index — the count itself is
resume-orchestration state, tracked live by
RepeatCounters (sched/repeat.rs),
not by the sensitivity table.
##N/clocking-block cycle delays reduce to this term, with no
second mechanism (SC-004, SC-005, SC-053): per ARCHITECTURE §6.5,
CycleDelayControl is resolved to absolute ticks at runtime, not
pre-resolved by codegen/elaboration — ##N relative to a clocking
block’s bound clock is semantically Repeat{count: N, inner: Edge{cell: <bound clock's cell>, edge: Posedge, iff: None}}. Because
RepeatCounters counts live firings of inner’s real signal rather
than precomputing an absolute tick offset, “the same compiled ##N
delay produces different absolute tick timing when its associated
clock’s period changes dynamically at runtime” (SC-053’s own
differentiating acceptance clause) holds by construction: there is no
cached tick offset to go stale. See sched::repeat’s own module doc
comment and sched::control’s
sc053_repeat_based_wait_re_reads_the_clocks_live_period_not_a_cached_tick_offset
for the proof against a deliberately irregular (non-periodic) clock.