A ripple-carry adder is small and slow, a prefix adder is larger and fast, and multipliers range from tiny shift-add to big trees. Writing a + b or a * b hides that choice: synthesis picks the architecture, so give it clear operators, deliberate widths and a real constraint.
4 lessons, about 19 min
assign y = a + b; and the design fails timing in the adder, what are your options in order of effort?(1) Check widths and signedness: an accidental extra-wide operand makes a bigger adder. (2) After checking the requirement, the constraint and the failing report, try a tighter constraint as a supported experiment and compare timing and area afterwards; a faster architecture is not guaranteed. (3) Restructure the arithmetic (reduce the number of operands, use carry-save form). (4) Pipeline the operation.
Do | Avoid |
|---|---|
Write | Widening an operand by accident and paying for a bigger adder |
Constrain the clock so the tool can pick a faster adder | Hand-instantiating full adders to beat synthesis |
The whole topic on one page, taken from each lesson's Remember box. Read it before an interview, or print it.
Adder Building Blocks
Full adder: sum = a ^ b ^ cin, cout = majority(a, b, cin).
Subtract with y = a + (b ^ {N{sub}}) + sub.
On subtract, cout = 1 means no borrow. Signed overflow uses the effective b after the XOR.
Rule of thumb: in production RTL write a + b and a - b; build adders by hand only to understand them.
Ripple Carry and Carry Lookahead
g = a & b and p = a ^ b. Then c(i+1) = g(i) | p(i) & c(i).
Ripple depth grows linearly with N; a prefix adder grows near log N at the cost of area and wiring.
Carry-skip and carry-select adders sit between the two: more area for a shorter worst path.
Rule of thumb: write a + b and constrain it; let the tool pick the adder.
Shift-Add Multiplier
An N x N multiply has N partial products and a 2N-bit result.
The bare loop is combinational and promises no cycle count. A sequential version reuses one adder over W cycles.
Signed operands need sign-extension tricks or Baugh-Wooley, because the sign bit has negative weight.
Wallace-Tree Multiplier Intuition
A carry-save adder turns three rows into two (a sum vector and a carry vector) with no carry propagation, and keeps the total value.
Each level cuts the rows by 2/3, so depth grows like log 1.5 of the row count.
Only the last step is a real carry-propagate adder.
Rule of thumb: write a * b and let synthesis choose the tree.
Mini project: a 32-bit leading-zero counter and normaliser
Code lab: Build a full adder
Code lab: Build an 8-bit ripple-carry adder
Practice question: An iterative shift-and-add multiplier
Interview: run a mock interview on this topic