Datapaths: Why Multipliers Hurt
Watch an equivalence check grow with multiplier width, see why both BDDs and SAT struggle, and learn to change the question when a check will not finish.
- Lesson
- F6.3
- Time
- 15 min
- Runs on
- SymbiYosys
- Check
- 4 questions
A team replaced a vendor multiplier with their own and asked the equivalence tool to sign it off. The 8-bit version proved quickly; the 32-bit version ran all weekend with no answer, and so did a second tool. Neither tool was broken.
a * b against the unrolled shift-add multiplier, one run per width and strategy. Widths 4 to 8, where all three finished.- sat
- sby yices
- sby bitwuzla
Read the plot as a table
| Operand width | sat | sby yices | sby bitwuzla |
|---|---|---|---|
| 4 bit | 204 ms | 304 ms | 405 ms |
| 4.5 bit | 203.5 ms | 304 ms | 354.5 ms |
| 5 bit | 203 ms | 304 ms | 304 ms |
| 5.5 bit | 253 ms | 354.5 ms | 354 ms |
| 6 bit | 303 ms | 405 ms | 404 ms |
| 6.5 bit | 855 ms | 555 ms | 604 ms |
| 7 bit | 1.407 s | 705 ms | 804 ms |
| 7.5 bit | 9.723 s | 1.356 s | 1.305 s |
| 8 bit | 18.04 s | 2.007 s | 1.807 s |
Measured on a laptop with the pinned suite; times are EQY wall clock, resolved to about 0.1 s. The table below carries each strategy to its first cut-off.
The Curve
| Width | sat (bit-level SAT) | sby, smtbmc yices | sby, smtbmc bitwuzla |
|---|---|---|---|
| 4 | 0.2 s | 0.3 s | 0.4 s |
| 5 | 0.2 s | 0.3 s | 0.3 s |
| 6 | 0.3 s | 0.4 s | 0.4 s |
| 7 | 1.4 s | 0.7 s | 0.8 s |
| 8 | 18.0 s | 2.0 s | 1.8 s |
| 9 | stopped at 20 s | 13.2 s | 6.0 s |
| 10 | not run | stopped at 20 s | 17.4 s |
| 11 | not run | not run | stopped at 20 s |
Each strategy runs from 4 bits upward and stops at its first cut-off; "not run" means a smaller width had already exceeded 20 s.
Each extra bit multiplies the time. Bit-level SAT takes 1.4 s at 7 bits and 18.0 s at 8, then passes the 20 s budget at 9. The word-level runs last longer: Yices to 9 bits, Bitwuzla to 10.
Two or three bits of headroom is all a better solver bought. At 32 bits the same growth means no answer on any machine.
Why Multipliers in Particular
Read the diagram as text
- Comparator, a < b: BDD size grows with the width (F2.6)
- Multiplier, middle bit: BDD size exponential for every variable order
- SAT on the miter: two unlike structures, little to learn from
- Word-level SMT: `*` is one operation, until it is bit-blasted
- Multiplier, middle bit → SAT on the miter: no compact form
- Word-level SMT → SAT on the miter: unlike sides
A drawing of the argument, not node counts. The multiplier result is Bryant's 1986 lower bound.
Bryant proved in 1986 that the BDD of a multiplier's middle output bit is exponential in the width for every variable order. The comparator BDD of F2.6 fits on a page; the multiplier's outgrows practical memory somewhere in the mid-teens of bits.
SAT does not store the function, but it searches it. Here one side is * and the other a chain of shifted adds, so the solver finds little shared structure to learn from (F2.2).
What a Word-Level Solver Changes
module mul(input [3:0] a, b, output [7:0] p);
assign p = a * b;
endmodule
module mul(input [3:0] a, b, output reg [7:0] p);
integer i;
always @* begin // the shift-add multiplier of F2.2, unrolled: one partial product per bit of b
p = 0;
for (i = 0; i < 4; i = i + 1)
if (b[i]) p = p + ({4'd0, a} << i);
end
endmodule
An SMT solver sees * as one operation and can rewrite it when both sides are alike. Here the sides differ, so it lowers the multiply to gates internally and the problem returns to SAT. It starts later and climbs the same way.
Bitwuzla held out one bit longer than Yices on this pair. That ordering is a property of this design, not of the solvers, so measure on your own block before choosing an engine (F4.7).
Change the Question
| Technique | What it buys |
|---|---|
| Partition at register boundaries | each piece is a small cone; a pipelined multiplier splits naturally |
| Prove the partial-product generator and the adder tree separately | two easy checks in place of one hard one |
| Reduce a width-independent structure | valid for a FIFO's data path, not for a multiplier's carries |
| Datapath tools with arithmetic solvers | word-level rewriting and algebraic methods built for multiplication |
Commercial datapath validation compares a C or SystemC model with the RTL using the last row. The open suite has none of it.
Width reduction (F4.5) is the trap: a 4-bit multiplier proof says nothing about the carry chains of a 32-bit one. When a check will not finish, decompose it.
A decomposition is only sound if the pieces cover the whole. Prove each partial product against its slice of the reference, then prove the adder tree sums its inputs. Together the two proofs cover the multiplier with no single hard cone.
Asked in Interviews
| Question | Answer |
|---|---|
| Why are multipliers hard for equivalence tools? | BDDs of a multiplier's middle bit are exponential for every variable order (Bryant 1986), and unlike implementations give SAT little shared structure. Time grows faster than any machine. |
| What is datapath validation? | Comparing a C or SystemC reference with the RTL using solvers built for arithmetic, plus partitioning. |
| The check does not finish. What do you do? | Partition at register boundaries, check the arithmetic blocks separately, and reduce only what is truly width-independent. |
Try It
[gold]
read_verilog -sv design.sv
prep -top mul
[gate]
read_verilog -sv gate.sv
prep -top mul
[strategy sby]
use sby
depth 1
engine smtbmc yicessby strategy (depth 1) for the other two series.[gold]
read_verilog -sv ref.sv
prep -top mul
[gate]
read_verilog -sv sa.sv
prep -top mul
[strategy sat]
use satRun 4 bits
As loaded: EQY PASS: every partition proved in 0.6 s.
Drop a partial product
In gate.sv add
&& i != 2to theif: UNKNOWN: equivalence not proven. The runner cannot show whether the failure is reachable; with no cut points inside this one partition, it is.Grow it
Set W to 6 in both files: EQY PASS: every partition proved in 0.6 s. Then try 9 and watch the budget.
design.sv
gate.sv
Use assert property (@(posedge clk) ...);. Leave blank for immediate assertions in the design.
Inputs are free unless constrained. Run to find a counterexample or check a proof.
Model: one positive-edge clock, binary data. Sampled history requires declaration-initialized variables; primary-input history is unsupported.
SBY summary and log
Check Yourself
Remember
- Equivalence of unlike multipliers grows exponentially with width, on every solver.
- BDDs of a multiplier's middle bit are exponential for every variable order (Bryant 1986).
- Word-level solvers start later on the same curve; they bit-blast unlike structures.
- When a check will not finish, decompose it: register boundaries, partial products, adder tree.