The interviewer asks for an 8-bit signed adder: how wide is the result, and how does the design know when the true sum no longer fits.
The question tests signedness and width discipline. Silent truncation is a silicon bug that small test values never expose.
Declare signed on the operand signals, not only on literals. Size the sum to the full precision, 9 bits for 8-bit operands, and carry a flag when the truncated result differs.
Truncation to 8 bits preserves the value exactly when the two top sum bits agree. When they disagree, the low byte has wrapped.
Coding | Outcome |
|---|---|
Both operands | Correct full-precision result |
Mixed signed and unsigned operands | Expression is unsigned: sign lost |
8-bit result, small test values | Wraps silently on large magnitudes |
8-bit result plus overflow flag | Defined behaviour on every input |
Why does mixing signed and unsigned bite? When any operand is unsigned, the whole expression is unsigned. A signed operand is then treated as a large positive value.
How wide is an 8 by 8 multiply? 16 bits. A multiply needs the sum of the operand widths, while an addition of two W-bit numbers needs W plus one.
When is truncation acceptable? When the design proves the upper bits redundant, for example a range check upstream. The proof belongs in the testbench, not in optimism.
“Cast the result with $signed” is too late. The expression width and signedness are fixed before the cast applies.
“The testbench passed with typical values” proves nothing about extremes. Exhaustive small widths, or directed extremes plus random, are the standard.
// bad-example
module trunc_quiet (
input logic signed [7:0] a, b,
output logic signed [7:0] sum
);
assign sum = a + b;
endmoduleRead the columns from bit 8 down to bit 0. Bit 8 of each operand is its sign extension.
Bits 5 to 7: bit 5 is 1 + 1 = 0 carry 1; bit 6 is 1 + 1 + 1 = 1 carry 1; so bit 7 becomes 1.
Bit 8: both operands are positive, so the 9-bit sum keeps a 0 sign bit: +192.
The 8-bit result keeps only bit 7 as its sign, which is 1, so the same bits read as -64.
signed [7:0] and the sum is signed [8:0]. For which sums does the 8-bit wrap differ from the true value?Exactly when the top two sum bits disagree. That condition is the truncation flag in the solution below.
The full-precision adder with a truncation flag, checked against an integer reference over all 65536 operand pairs.
module signed_add #(parameter int W = 8) (
input logic signed [W-1:0] a, b,
output logic signed [W:0] sum,
output logic signed [W-1:0] wrapped,
output logic dropped
);
assign sum = a + b;
assign wrapped = sum[W-1:0];
assign dropped = (sum[W] != sum[W-1]);
endmodule