Two branches that cannot execute together may share hardware. The tool checks mutual exclusion first, then whether the operators are compatible.
Addition, subtraction and comparison on the same operands are compatible. They all reduce to addition around one carry chain.
Operation | Shared implementation |
|---|---|
+ | One adder. |
- | The same adder with an inverted subtrahend and carry-in 1. |
< | The same subtract, keeping only the carry or sign decision. |
== | A bitwise compare. It merges only when it shares the operands, and the tool decides. |
A compare with one signed side is evaluated as signed. Mark both sides explicitly so the tool builds the intended comparator.
The alumacc pass rewrites compatible arithmetic cells into ALU cells. Each source operation gets an ALU cell, and the standalone add and subtract disappear.
The block below builds a two-way ALU. Its assertions pin one add and one subtract before the pass, and two ALU cells with no standalone add or subtract after it.
read_verilog <<EOV
module alu2(input [7:0] a, b, input sel, output [7:0] y);
assign y = sel ? (a + b) : (a - b);
endmodule
EOV
hierarchy -top alu2
proc
opt_clean
select -assert-count 1 t:$add
select -assert-count 1 t:$sub
alumacc
select -assert-count 2 t:$alu
select -assert-count 0 t:$add
select -assert-count 0 t:$sub
stat -liberty course.lib
log PASS: add and subtract become ALU cellsOrdering needs only the carry out of a shared subtract. Equality needs only a zero detect on the same difference.
4-bit unsigned example: a = 11 (1011), b = 6 (0110)
bitwise NOT of b within 4 bits: 15 - 6 = 9 (1001)
a - b as addition: 11 + 9 + 1 = 21; 21 - 16 = 5; check 11 - 6 = 5
carry out is 1 because 21 >= 16, so a >= b holds
a < b is false and a == b is false from the same subtractOne $add, one $sub and steering. After the pass, two $alu cells with no standalone $add or $sub.
No. Unsigned 255 < 1 is false, while signed -1 < 1 is true. The same bits order differently.