A register holds bits, and declarations decide what they mean. Signedness and width decide comparison, shifts, extension and overflow.
6 lessons, about 22 min
Exactly 2ᴺ. Interpretation only changes which numbers those patterns stand for (0…2ᴺ−1 unsigned, or −2ᴺ⁻¹…2ᴺ⁻¹−1 signed).
The whole topic on one page, taken from each lesson's Remember box. Read it before an interview, or print it.
Representation Drives Behavior
Any unsigned operand makes the whole arithmetic or comparison expression unsigned.
The shift amount is the exception: it does not change the signedness of the shifted value.
>> never sign-extends; >>> on a signed operand keeps the sign, but it rounds toward minus infinity: -5 >>> 1 is -3, while -5 / 2 is -2.
Rule of thumb: declare numbers signed and raw bit patterns unsigned, and cast explicitly between them.
Binary and Hexadecimal Conversion Habits
One hex digit is four bits: group from the right and translate each group.
A sized literal is <size>'[s]<base><digits>. Write a negative value with a separate unary minus.
An unsized literal or bare 10 is at least 32 bits wide and can widen the whole expression.
Rule of thumb: size every literal.
Two's Complement Intuition
The top bit has negative weight. N bits cover -2^(N-1) to 2^(N-1) - 1.
Arithmetic is modulo 2^N: carry marks the unsigned boundary, signed overflow marks the signed one.
The most negative value has no positive counterpart. Negate, abs and saturate blocks must handle it.
Rule of thumb: negate by inverting every bit and adding one, but sign-extend first if you need the exact result.
Sign Extension, Zero Extension and Casting
Zero extension is correct for unsigned values and sign extension for two's complement values.
A concatenation is unsigned even when it copies the sign bit.
A cast changes interpretation, not bits. To mix operands, zero-extend the unsigned one into a wider signed type first.
Rule of thumb: widen first with the fill you mean, then do the arithmetic in one signedness.
SystemVerilog Signed Arithmetic Pattern
An add of two N-bit numbers needs N+1 bits and a multiply needs 2N.
In a direct assignment the wide destination sets the arithmetic width, but it cannot recover bits lost inside a narrow intermediate.
>>> divides a signed value by 2^k and rounds toward minus infinity: -5 >>> 1 is -3.
Rule of thumb: narrow only at the end, and only on purpose.
Overflow Detection Patterns
Carry is the unsigned flag. Signed overflow happens only when both operands have the same sign and the result sign differs.
For a - b, form a + ~b + 1: the carry means no borrow, and overflow needs operands of different signs.
The two flags are independent, so compute both from one verified module.
Rule of thumb: pick the flag that matches how the bits are interpreted.
Mini project: a 4-bit ALU with flags and an exhaustive bench
Code lab: Build a signed comparator
Code lab: Build saturation logic
Interview: run a mock interview on this topic