← Design Verification Interviews
Interview Question · Code Reading
The Negative Number That Was Not Smaller
The Question
The interviewer asks
What does this print, and why?
logic signed [7:0] s = -1;
logic [7:0] u = 1;
initial if (s < u) $display("negative is smaller");
else $display("surprise");You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
It prints surprise. An expression is signed only if every operand is signed. So the unsigned u makes the whole comparison unsigned, and s is read as 255. Declaring s as signed does not help. Make both operands signed, widening the unsigned one first with $signed({1'b0, u}) so that a large value cannot flip negative.
s < u is. Arrows show operands feeding a rule and its result.Read the diagram as text
- logic signed [7:0] s = -1: bits 1111_1111
- logic [7:0] u = 1: unsigned
- Is any operand unsigned?: yes, u is
- Unsigned compare: 255 < 1: false, so it prints surprise
- $signed({1'b0, u}): add a zero sign bit, then make it signed
- Signed compare: -1 < 1: true
- logic signed [7:0] s = -1 → Is any operand unsigned?
- logic [7:0] u = 1 → Is any operand unsigned?: unsigned
- Is any operand unsigned? → Unsigned compare: 255 < 1: whole compare unsigned
- logic [7:0] u = 1 → $signed({1'b0, u}): the fix
- $signed({1'b0, u}) → Signed compare: -1 < 1: both signed
Declaring s as signed is not enough. Both operands must be signed for a signed comparison.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Fresher)
A good fresher answer predicts surprise and gives the reason: one unsigned operand makes the whole comparison unsigned.
What Interviewers Listen For (Junior)
A good junior answer fixes it by widening before $signed. It explains why a plain $signed(u) goes wrong for values of 128 and above.
What Interviewers Listen For (Mid-Level)
A good mid-level answer applies the same rule to loop counters and parameter arithmetic. It turns on lint warnings for comparisons that mix signed and unsigned values.
Cross-Questions
Where the interviewer goes next. Open a node to practise that follow-up.
WhyWhat IfProve ItBreak ItCompare
- The Negative Number That Was Not Smaller
-
WhyWhy the Operands Decide SignednessL1 JuniorL2 Mid-Level
Why did the language designers make signedness depend only on the operands, not on where the result goes?
2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
The standard evaluates an expression in two steps. First, the operands fix the width and signedness of each part. Then the operands are extended to that size. Keeping the result target out of the first pass means one expression has one meaning wherever it appears. The price is the trap you just saw, so the rule is to make operands agree.
Self-Check
Tick each key point you covered in your answer.
Half-Truth
"Signed arithmetic only matters for division."
It also changes comparisons, right shifts with
>>>and sign extension when a narrow value is widened.Source IEEE 1800-2017 §11.4.10
-
What IfA Negative Literal Next to an Unsigned VectorL1 JuniorL2 Mid-Level
What if you write
a < -1withadeclaredlogic [7:0]?2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
One unsigned operand makes the whole comparison unsigned. Both sides are sized to 32 bits, the width of the literal. So
-1becomes32'hFFFF_FFFF, anda < -1is true for every 8-bita. Make the unsigned side signed and wide enough, as inint'(a) < -1.Self-Check
Tick each key point you covered in your answer.
Misconception
"A negative literal keeps the comparison signed."
Signed arithmetic needs every operand to be signed. One unsigned vector turns the whole comparison unsigned.
Source IEEE 1800-2017 §11.8.1
-
CompareSigned Cast vs Widening FirstL1 JuniorL2 Mid-Level
Compare fixing the comparison with
$signed(u)and with$signed({1'b0, u}). When do they differ?2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
$signed(u)reinterprets the same 8 bits, so any value of 128 or more becomes negative: 200 turns into -56.$signed({1'b0, u})first adds a zero sign bit, so 200 stays 200 as a 9-bit signed value. They agree for small values, which is why the plain cast passes a quick test and fails in the field.Two casts of u = 200Expression Bits Value s < it, withs = -1$signed(u)1100_1000-56 0 $signed({1'b0, u})0_1100_1000200 1 The values are the output of the run on this question.
RUNIcarus Verilog · in your browserExpected:$signed(u) = -56, so s < $signed(u) is 0$signed({1'b0,u}) = 200, so s < it is 1Self-Check
Tick each key point you covered in your answer.
Misconception
"
$signedmakes the value signed without changing it."It keeps the bits, not the value. For the top half of the unsigned range those bits mean a negative number.
Source IEEE 1800-2017 §11.7
-
Break ItThe Down-Counter That Never StoppedL1 Junior
A test hangs in this loop. What is wrong?
systemverilog for (bit [3:0] i = 3; i >= 0; i--) begin drive_lane(i); end2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
An unsigned counter is never below zero, so
i >= 0is always true; after 0 it wraps to 15 and keeps going. Use a signed loop variable such asint, or count up.Self-Check
Tick each key point you covered in your answer.
Misconception
"The loop runs four times and stops at 0."
The twin guards the loop at 20 passes; it hits the guard with the 4-bit counter and runs exactly four times with
int.Run It
A 4-bit unsigned down-counter with a guard so the run ends.
RUNVerilator · simulator serviceExpected:iterations=21FAIL: an unsigned counter is never below 0, so i >= 0 is always trueSee the Fix
module tb; int iters = 0; initial begin // Visit 3, 2, 1, 0 with a 4-bit counter. for (int i = 3; i >= 0; i--) begin iters++; if (iters > 20) break; // guard, so the run ends end $display("iterations=%0d", iters); if (iters > 4) $display("FAIL: an unsigned counter is never below 0, so i >= 0 is always true"); else $display("PASS: the loop ran four times"); end endmodulePrints:
iterations=4PASS: the loop ran four times -
Prove ItSolve 1.4.1: Safe Opcode DecoderSimulator-graded
Show it, don't just say it: this Silicon Lab problem is graded by the simulator.
What People Get Wrong
Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.
Misconception
"s is declared signed, so the comparison is signed."
Signedness comes from all the operands, not from one declaration. The twin compares -1 with 1 and takes the unsigned branch.
Run It
A signed -1 compared with an unsigned 1.
FAIL: one unsigned operand made the compare unsigned, so -1 became 255See the Fix
module tb;
logic signed [7:0] s = -1;
logic [7:0] u = 1;
initial begin
// The fix: both operands signed, u widened first so 255 cannot turn negative.
if (s < $signed({1'b0, u})) $display("PASS: -1 < 1");
else $display("FAIL: one unsigned operand made the compare unsigned, so -1 became 255");
end
endmodule
Prints: PASS: -1 < 1
Misconception
"Assign the result to a signed variable and the compare becomes signed."
The type of the left-hand side never changes how the operands of a relational operator are interpreted. Relational results are always one unsigned bit.
Source IEEE 1800-2017 §11.8.1
Buzzword Without Mechanism
Says "use $signed" without saying what it does to the bits.
$signed only reinterprets the same bits. It does not widen, which is exactly why $signed(8'd200) becomes -56.