"Multiple edge sensitive events found for this signal!" left the reader to
guess which signal and which line. Report the signal and, where the failing
sync action carries one, the source location.
(cherry picked from commit 7f791a4fb, emil/twines-proc-srcloc-rebased)
genrtlil records the case item as compare_src and the block as the case's
own src, so the actions inside a case point at the statements that wrote
them rather than at the selector. A $eq then stands for both sides of the
comparison it performs - the switch expression and the case value - the
$reduce_or over them for the case value, and the _CMP wire for the switch.
A mux passes its fused locations on to the wire it drives.
The gatemate fsm LUT counts go back to what they were before the source
work: the finer mapping restores the earlier covering.
Picks up the proc part of emil/twines-proc-srcloc-rebased:
b2d57e5d4 rtlil: add case_src to CaseRule
c74bc43cf proc_mux, genrtlil: make use of case_src
9bc771e05 proc_mux: copy switch src to _CMP wire
6182c7dd8 proc_mux: copy mux src to Y port
3d2e26815 kernel: add SwitchRule signal_src
cf3867bb1 proc_mux: include switch expression location in $eq src
A CaseRule's own src is where its body is; compare_src is where the case
is selected. A SwitchRule's own src is the whole statement; signal_src is
where its expression is. Both survive a clone and a cross-pool copy.
Also root the srcs a process holds outside its AttrObjects - one per
assignment, plus the two above - so garbage collection cannot free the
twines they point at.
A replayable .il names twines and source location sets by pool index, and
a design that has freed slots writes a set with gaps in it. Reading such a
file into a fresh design packed the survivors, so write, read, write did
not reproduce the file.
Let the pools intern at a caller-chosen index and use that while loading
into a design with no twines or srcs of its own, falling back to the old
remapping when the file's numbering does not fit this build.
A CaseRule takes the location of its case item, so the $eq that decodes it
lands on the compare rather than on the block, and a mux keeps the fused
action locations it was given instead of inheriting the case's.
A flop fuses the process location with the locations of the wires it drives.
Track, per (snippet, case), the source location of the action that assigns
that snippet, and fuse the locations of every case feeding a mux tree onto
the resulting cell, falling back to the case's own location where an action
carries none. A mux now points at the assignments it came from instead of
at the enclosing switch.
Squashes the proc_mux commits of emil/proc_mux-better-src:
a1be8fa88 proc_mux: emit fused action location src attributes on procmuxes
d6b3e3a5a proc_mux: refactor
0cac2c4b9 proc_mux: default to case src when action src is missing
affd6faa3 proc_mux: optimize source map locality for index density
59137d2a0 proc_mux: add comments
roundtrip-src.sh checks that an `srcs` section survives write/read and a
design push/pop unchanged, and that -readable resolves the handles.
no-pipe-leaf.sh checks that fusing locations never bakes a '|'-joined
string into a twine leaf.
Source locations move off the attribute dict into a dedicated SrcRef on
AttrObject, interned in a per-design SrcPool that hash-conses sets of
location twines. Locations share their file prefix with each other through
the twine pool, and objects that fuse (opt_merge, share, ff/mem rewrites)
carry the union of their inputs' locations instead of a '|'-joined string.
write_rtlil emits an `srcs` section of location sets alongside `twines`;
read_rtlil resolves `\src "@N"` back to a handle and still accepts a plain
location string. -readable renders the locations as text.