Verilog: don't treat 'integer' loop counters as synthesis driver conflicts - #2049
Draft
kroening wants to merge 1 commit into
Draft
Verilog: don't treat 'integer' loop counters as synthesis driver conflicts#2049kroening wants to merge 1 commit into
kroening wants to merge 1 commit into
Conversation
Module-level 'integer' variables are idiomatically used as loop counters and combinational scratch. They are elaboration-only: the synthesis pass never turns them into state (synth_assignments skips them), yet assignment() still tracked their assignments for driver and assignment-type conflicts. When such a variable was (blocking-) assigned in more than one always/initial block -- e.g. a shared 'for' loop index -- this produced a spurious "conflict with previous assignment" or "conflicting assignment types (new: clocked, old: combinational)" error, even though only one block's value is ever observable. Exempt variables carrying the Verilog 'integer' type from assignment-type and member/driver-conflict tracking. Fixes elaboration of LogikBench basic/crossbar, blocks/viterbi (signal j) and large/qr (signal k). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Part of the LogikBench elaboration triage (
benchmarking/logikbench.sh,report at https://diffblue.github.io/hw-cbmc/). This addresses the
synthesis driver-conflict bucket: circuits that failed
ebmc --bound 0during synthesis with either
X(new: clocked, old: combinational)".Both are thrown from
src/verilog/verilog_synthesis.cppwhile tracking, persignal, which bit-ranges/members have already been assigned so that a signal
driven twice in an unmergeable way is rejected.
Root cause (differs from the original branch-merge / generate-instance hypotheses)
The tracking in
assignment()runs for every assigned symbol, butsynth_assignments()never turns Veriloginteger-typed variables into stateor wires — they are elaboration-only scratch. Module-level
integervariables are idiomatically used as
for-loop counters and shared acrossseveral
always/initialblocks. Because the member tracking persists acrossblocks (
move_assignments()runs at each block's end), a loop counter such asinteger iassigned in two blocks was flagged as a spurious multiple-driverconflict:
(the reported location is the
for (i = 0; …)header, i.e. the counter, notthe data signal);
types (new: clocked, old: combinational)".
Only the last block's value of such a counter is ever observable, so the reuse
is benign.
Fix
Exempt symbols carrying the Verilog
integertype(
type.get(ID_C_verilog_type) == ID_integer) from assignment-type andmember/driver-conflict tracking — consistent with
synth_assignments(), whichalready excludes them from synthesis. One-line guard plus a comment; no change
to how genuine state/wire signals are checked.
Circuits fixed (3)
basic/crossbarinteger iacross twoalways @(*)blocks/viterbiinteger jcombinational vs clocked (rtl/viterbi.v:121)large/qrinteger kcombinational vs clocked (rtl/qr.v:90)All three now elaborate (
ebmc --bound 0→ exit 0/10).Circuits deliberately left failing (12) — genuine conflicts / real EBMC limitation, not false positives
blocks/reedsolomon— genuinely invalid RTL. Registers_nzis drivenby two separate
always @(posedge clk)blocks (rs_syndrome.v:58 and:72/:75). This is a real multiple-driver situation that hardware synthesis
tools also reject; EBMC is correct to error.
11 koios circuits (
attention_layer,clstm_like_small,clstm_like_medium,conv_layer,conv_layer_hls,dla_like_small,dla_like_medium,eltwise_layer,spmv,tpu_like_small_os,tpu_like_small_ws) — all conflict on a.ramarray inside a truedual-port RAM (two write ports,
ram[address_a] <= data_aandram[address_b] <= data_b, in two separate clocked blocks, non-constantindices). EBMC models array writes as a single per-signal "next value"
(last-writer-wins), so it cannot represent two independent write ports; the
conflict check is honestly reporting that limitation. Suppressing it would
silently drop one write port and produce a semantically wrong model, so these
are left failing. Real multi-write-port memory support is a separate, larger
enhancement.
Regression tests
regression/verilog/shared-integer-loop-variable/:two_combinational_blocks— sharedintegercounter in twoalways @(*)(models crossbar / the koios loop-counter idiom);
combinational_and_clocked— sharedintegercounter in a combinational anda clocked block (models viterbi/qr).
Both
PROVEDafter the fix and would previously have hit the conflict errors.make -C regression/verilog testpasses (no other tests regress; no existingtest relied on the removed conflict behaviour).
Known follow-up (out of scope here)
After the fix,
blocks/viterbigets past the conflict error but its synthesisis very slow/heavy (min-path-metric logic explodes into a large
WITH/wirenetwork), so it may still not pass CI within resource limits. That is a
separate synthesis-performance issue, not a driver-conflict one, and is not
addressed in this PR.