Skip to content

Verilog: fold Verilog-specific constructs when propagating constants in synthesis - #2053

Draft
kroening wants to merge 1 commit into
mainfrom
kroening/logikbench-loop-guard-constant-folding
Draft

Verilog: fold Verilog-specific constructs when propagating constants in synthesis#2053
kroening wants to merge 1 commit into
mainfrom
kroening/logikbench-loop-guard-constant-folding

Conversation

@kroening

@kroening kroening commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

When synthesising a blocking assignment, synth_assign tries to simplify
the right-hand side to a constant so the value can be propagated (needed,
among other things, to unroll for/while loops by evaluating their guard
each iteration). It used the plain simplifier, which does not know how to
reduce Verilog-specific constructs such as replication ({n{x}}) to a
constant.

As a result a loop whose bit-vector loop variable is initialised with a
replication, e.g.

for(data_mask = {1'b1, {DW-1{1'b0}}}; data_mask != 0;
    data_mask = data_mask >> 1)

left data_mask non-constant, so synthesis reported "synthesis failed to
evaluate loop guard". Uses the Verilog-aware simplifier instead, which
lowers replication to a concatenation before folding. The result is only
used when it is constant, so non-constant right-hand sides are unaffected.

This is the root cause of the loop-guard failures for the LogikBench
blocks/ethmac (rtl/eth_lfsr.v:235) and blocks/lfsr (rtl/lfsr.v:235)
benchmarks.

New regression test: regression/verilog/synth_loop_guard_bitvector1.

…in synthesis

When synthesising a blocking assignment, synth_assign tries to simplify the
right-hand side to a constant so the value can be propagated (needed, among
other things, to unroll for/while loops by evaluating their guard each
iteration). It used the plain simplifier, which does not know how to reduce
Verilog-specific constructs such as replication ({n{x}}) to a constant.

As a result a loop whose bit-vector loop variable is initialised with a
replication, e.g.

  for(data_mask = {1'b1, {DW-1{1'b0}}}; data_mask != 0;
      data_mask = data_mask >> 1)

left data_mask non-constant, so synthesis reported "synthesis failed to
evaluate loop guard". Use the Verilog-aware simplifier instead, which lowers
replication to a concatenation before folding. The result is only used when
it is constant, so non-constant right-hand sides are unaffected.

This is the root cause of the loop-guard failures for the LogikBench
blocks/ethmac (rtl/eth_lfsr.v:235) and blocks/lfsr (rtl/lfsr.v:235)
benchmarks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant