ASLR-dependent ConstEval seeding let E4 miss OOR counterexamples; use a
deterministic seed and force OOR key collisions. Add I9 (NB=12) for the
thermometer fallback path Greptile flagged.
Co-authored-by: Cursor <cursoragent@cursor.com>
The round-robin (and PE/CLZ/CTZ) fingerprints pin candidate request/
start/select signals as free ConstEval inputs and evaluate the encoder
output cone. ConstEval::eval() re-computes and re-set()s the FULL output
of every combinational cell it needs. If a pinned bit is a combinational
cell output and a sibling output bit of that same cell is pulled into the
cone, evaluating the sibling re-sets the pinned bit to the cell's real
value, contradicting the free value we pinned and tripping the assertion
`current_val[i].wire != NULL || current_val[i] == value[i]` in
kernel/consteval.h.
The earlier clean_set_signals() guard only rejected constant/aliased
bits; it did not ensure the pinned signals form a valid cut. Candidates
are gathered purely by width, so an internal combinational wire (e.g. a
slice of a wider arithmetic result) can be pinned, which is exactly what
crashed on veer_speed1/picorv32/murax/raygentop.
Add is_valid_consteval_cut(): a pinned bit is a safe leaf when it is a
primary input, sequential-cell output or undriven (absent from
bit_to_driver, which holds combinational drivers only); a combinational
output is safe only if that cell's entire output lies within the pinned
cut. Apply it in both fingerprint() and fingerprint_rr(). Declining an
unclean cut only forgoes a possible rewrite, never yields a wrong one,
and the intended arbiter inputs (request ports, idx_last flop outputs)
remain valid cuts so real round-robin patterns still rewrite.
Co-authored-by: Cursor <cursoragent@cursor.com>
The round-robin detector fed sigmap(wire) signals straight into
ConstEval::set() while sweeping test vectors. On real designs a candidate
bus can have bits tied to constants, repeated bits, or a req/start pair
that alias to the same net after sigmap. ConstEval::set() asserts
(current_val[i].wire != NULL || current_val[i] == value[i]) when asked to
re-pin such a bit to a conflicting value, crashing the pass
(consteval.h:83) on designs like veer/picorv32/murax/raygentop under
formal synthesis.
Add clean_set_signals() and reject any fingerprint candidate whose
set-signals contain constant bits, repeated bits, or overlap each other,
in both the priority-encoder and round-robin paths. Skipping an unclean
candidate only forgoes a possible rewrite; it never produces an incorrect
one. Clean candidates (the intended patterns) are unaffected.
Co-authored-by: Cursor <cursoragent@cursor.com>
The max_pairs budget was a single running counter shared across all
req_wire iterations, so once a start-candidate-heavy first req size
exhausted it, every later req size broke on its first start candidate and
was silently skipped. Reset the budget per req_wire so all req sizes get
a fair chance. (Completeness only; fingerprint_rr still validates every
match, so this never affected correctness.)
Co-authored-by: Cursor <cursoragent@cursor.com>
Extend two existing opt passes and add one new pass to collapse
serial/dynamic-index structures that were leaving high logic depth:
- opt_first_fit_alloc: recognize the "coalesce-matrix" first-fit
allocator variant (same_cat[i][k] coalescing gated on the leader's
enable, driven from a raw input enable). Rewrite both the lane_slot
allocation and the xbar field gather from one shared log-depth scan.
- opt_prienc: detect round-robin / rotated-priority scans (req scanned
from idx_last downward with wraparound) and rewrite the depth-N
idx--/req[idx] mux chain to rotate -> log-depth priority-encode ->
unrotate.
- opt_priokey (new): recognize priority-by-key one-hot accumulators and
replace each dynamic taken[key] read ($shiftx/$bmux) with the
equivalent pairwise-key-compare reduction, dropping the wide dynamic
indexing. Supports -strict for full-key-range formal validation.
Each includes self-contained tests (equiv_opt / sat -prove-asserts,
mux-bound and negative cases) in tests/opt/.
Co-authored-by: Cursor <cursoragent@cursor.com>
- pack_lanes: assert elem_w < 32 and pack the full element width instead
of silently dropping bits >= 31.
- Remove the dead `cell` struct member and its unused assignment in run()
(every emit helper shadows it with its own local `cell`).
- Decorrelate the pseudo-random bc bits from en (independent mix) so they
no longer share an LFSR bit (e.g. en[7]/bc[0] for n=8).
- Add purpose comments to fingerprint_dsel and lane_of_bit.
Declined the std::stoi/std::stoll arg-parsing suggestion: it matches the
established convention in sibling passes (opt_argmax, opt_priority_onehot).
Co-authored-by: Cursor <cursoragent@cursor.com>
- update CMakeLists.txt to load two new files:
- SilimateConfig.cmake: sets Silimate configuration options and defaults
- SilimateVerific.cmake: compiles Verific library, optionally with Silimate modifications
- include silimate tests in test Makefile
Rewrite power-of-two indexed word selects to $bmux when the shift
amount already carries the scale as low zero bits.
Keep the rule to non-overlapping selections and bound the generated
mux ways. Add regressions for aligned shifts, padding, signed
extension, and shiftmul handoff cases.