← Design Verification Interviews

Interview Question · Code Reading

The Monitor That Copied to an Int

L0 FresherL1 Juniorsystemverilogdata typesfour state

The Question

The interviewer asks

A read monitor copies the DUT's rdata into an int before comparing it with the expected value. The DUT never reset the upper nibble. What does this print, and what has the monitor hidden?

systemverilog
module tb;
  // A read monitor copies the bus into an int before checking it.
  logic [7:0] rdata;
  int         seen;
  initial begin
    rdata = 8'bxxxx_0101;     // the DUT never reset the upper nibble
    seen  = rdata;            // the monitor's copy
    $display("rdata=%b seen=%0d", rdata, seen);
  end
endmodule
Reveal the Model Answer

It prints rdata=xxxx0101 seen=5. The copy into the two-state int turns every x and z bit into 0. So the copy looks like a clean 5, and any check after it passes. Keep DUT-facing data in four-state types such as logic, and test it with $isunknown before any conversion to a two-state type.

One DUT Value, Two Monitor CopiesOne DUT value is copied into a four-state variable and a two-state variable. Arrows show data moving by assignment; each token is the value as it arrives.
One DUT value, two monitor copiesOne DUT value is copied into a four-state variable and a two-state variable. Arrows show data moving by assignment; each token is the value as it arrives. dut DUT output dut_q logic [3:0], drives10xz four state seen4 logic [3:0]: keeps xand z two state seen2 bit [3:0]: only 0 and1 check Unknown check $isunknown(seen4) is1 check Value compare seen2 == 4'b1000 is1 seen4 = dut_qseen2 = dut_q
  1. The DUT drives 10xz

    The DUT drives 4'b10xz: bit 1 is unknown and bit 0 is not driven at all. The monitor copies this one value into two variables.

  2. Copy into logic

    The logic copy stores all four symbols, so seen4 reads 10xz, exactly the bits the DUT drove.

    Follow the calls, values and waits
    1. data 10xz: DUT output dut_q → seen4
  3. Copy into bit

    The bit copy turns each x and z bit into 0, with no warning. seen2 holds 1000, a value the DUT never drove.

    Follow the calls, values and waits
    1. data 10xz, stored as 1000: DUT output dut_q → seen2
  4. Check both copies

    $isunknown(seen4), a built-in that tests for any x or z bit, returns 1, so the four-state path can report the unknown bits. On the two-state path, seen2 == 4'b1000 is 1 and the check passes.

    More context

    The four-state path still needs $isunknown first: seen4 != 4'b1000 is x, and an if whose condition is x takes the else branch, as the next section and the example show.

    Follow the calls, values and waits
    1. data 10xz: seen4 → Unknown check
    2. data 1000: seen2 → Value compare
Read the diagram as text
  • DUT output dut_q: logic [3:0], drives 10xz
  • seen4: logic [3:0]: keeps x and z
  • seen2: bit [3:0]: only 0 and 1
  • Unknown check: $isunknown(seen4) is 1
  • Value compare: seen2 == 4'b1000 is 1
  • DUT output dut_q → seen4: seen4 = dut_q
  • DUT output dut_q → seen2: seen2 = dut_q
  • seen4 → Unknown check
  • seen2 → Value compare

The information is lost at the assignment to the two-state variable, before any check runs.

Two-state (0, 1)Four-state (0, 1, x, z)
bit, byte, shortint, int, longintlogic, reg, integer, time, every net

Only the right-hand column can hold an unknown. int and integer are both 32-bit signed, but only integer is four-state.

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Fresher)

A good fresher answer sorts the types into two-state and four-state at once. It predicts that the code prints seen=5 before anyone runs it.

Cross-Questions

Where the interviewer goes next. Open a node to practise that follow-up.

WhyWhat IfProve ItBreak ItCompareScale It

  1. The Monitor That Copied to an Int
  2. WhyWhy Two-State Types ExistL1 Junior

    If four-state types are safer, why does SystemVerilog have two-state types at all?

    Reveal the Model Answer

    A two-state bit needs half the storage and simpler arithmetic, which matters for large arrays, scoreboards and counters. Two-state types also match C, so they map cleanly across DPI, and random variables are generated as two-state values. Testbench-internal data rarely needs x, so it is the natural home for them.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "Two-state types exist for synthesis."

    Synthesis maps both families to the same gates; x is a simulation concept. The reasons are simulation speed, memory and C compatibility.

    Source Sutherland, RTL Modeling with SystemVerilog for Simulation and Synthesis, ch. 3.3

  3. CompareThree Ways to Ask Whether a Value Is UnknownL1 Junior

    Compare $isunknown(r), r === 'x and r == 'x as checks for an unknown bus.

    Reveal the Model Answer

    $isunknown is true when any bit is x or z, which is the check you want. === compares x and z bits literally, so r === 'x is true only when every bit is x and misses a half-driven bus. == returns x whenever an operand has an x bit, so it never gives a clean true. The run shows all three on xxxx0101.

    Three checks on r = 8'bxxxx_0101
    CheckResultWhy
    $isunknown(r)1At least one bit is x or z
    r === 'x0True only if every bit is x
    r == 'xxAny x bit makes == return x

    The values are the output of the run on this question.

    RUNIcarus Verilog · in your browser
    Edit the code, then run it
    Expected: isunknown=1 case_eq_all_x=0 logic_eq=x

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Junior)

    A good junior answer predicts all three results for a partly unknown value before running the code.

    Misconception

    "Write if (r == 'x) to catch an unknown bus."

    == with an x operand yields x, and if treats x as false, so that branch can never run. The run prints logic_eq=x.

    Source IEEE 1800-2017 §11.4.5

  4. Break ItAn Unknown Check That Fires Every Idle CycleL1 JuniorL2 Mid-Level

    You add assert property (@(posedge clk) !$isunknown(rdata)); and it fails on almost every cycle of a passing test. What is wrong with the check?

    log
    t=15 a_known failed: rdata=xxxxxxxx rvalid=0
    t=25 a_known failed: rdata=xxxxxxxx rvalid=0
    t=35 rvalid=1 rdata=3c  (scoreboard OK)
    t=45 a_known failed: rdata=xxxxxxxx rvalid=0
    Reveal the Model Answer

    The bus is allowed to be unknown when nothing is being transferred; only data that rvalid marks as valid must be known. Write rvalid |-> !$isunknown(rdata), and check the qualifier itself with a separate unconditional !$isunknown(rvalid) after reset.

    An unreset register on the read bus
    01234567rst_nrervalidrdatax5arvalid is 1, rdata is x: a real failure

    In cycles 0 to 3, rdata is x while rvalid is 0, which is legal. A check gated by rvalid fails only at cycle 4.

    Self-Check

    Tick each key point you covered in your answer.

    Wrong Altitude

    "Reset rdata in the DUT so the assertion stays quiet."

    That adds reset logic to a datapath to satisfy a wrong check. Many designs leave data unreset on purpose to save area; the protocol only promises known data when it is valid.

  5. What IfA Floating Bus in a Two-State VariableL1 Junior

    Asked if they only mention x

    What if the DUT releases the bus (drives z) instead of leaving it x?

    Reveal the Model Answer

    The result is the same: z also converts to 0 in a two-state variable, so an undriven bus reads as zeros. $isunknown treats z like x, so the same check before the copy catches both.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "A z reads as 1, because the bus floats high."

    Pull-ups exist only if the design models them with a pullup or a tri1 net. A plain z converts to 0 in two-state.

    Source IEEE 1800-2017 §6.11.2

  6. Prove ItSolve 1.1.3: The False-Pass MonitorSimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem 1.1.3

  7. Scale ItKeeping Unknowns Visible Across a Chip-Level BenchL3 Senior

    At chip level much of the environment is two-state, and the emulation runs are two-state too. How do you stop X bugs from escaping?

    Reveal the Model Answer

    Draw the line at the DUT boundary: interfaces and monitors stay four-state, and every bus gets a valid |-> !$isunknown(data) assertion bound to it. Reset and power-up scenarios run on a four-state simulator as a sign-off item. Emulation normally runs two-state; X modes exist but cost speed, so reset-state X checks belong in four-state simulation. Two-state is allowed only behind that boundary, where speed matters and nothing samples the DUT.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Senior)

    A good senior answer says which runs can see an x and which cannot. It makes the four-state reset run a sign-off item, not a hope.

    Half-Truth

    "Emulation covers it; it runs a million times more cycles."

    Emulation normally runs two-state, so a missing reset reads as 0 or 1. X modes exist but cost speed, so treat reset-state X checks as a four-state simulation item.

    Source ASIC Point engine notes (Verilator 5.052 SVA probes), row "x/z values" (how a two-state engine reads an X)

What People Get Wrong

Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.

Misconception

"int is four-state, like integer; only bit is two-state."

int belongs to the two-state family with byte and longint. The twin copies xxxx0101 into an int and gets a clean 5; a logic copy keeps the x.

Run It

The monitor copies an x-carrying bus into an int. Is the x still there?

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: seen=00000101 FAIL: int is two-state; the x became 0 and the copy looks like a clean 5
See the Fix
module tb;
  logic [7:0] rdata;
  logic [7:0] seen;   // the fix: keep the copy four-state
  initial begin
    rdata = 8'bxxxx_0101;
    seen  = rdata;
    $display("seen=%b", seen[7:0]);
    if ($isunknown(seen)) $display("PASS: the copy still carries the x, so the check can report it");
    else $display("FAIL: int is two-state; the x became 0 and the copy looks like a clean 5");
  end
endmodule

Prints: seen=xxxx0101 PASS: the copy still carries the x, so the check can report it

Half-Truth

"Make everything two-state; it simulates faster."

The speed-up is real for counters and testbench bookkeeping. On data sampled from the DUT, it hides a missing reset or an undriven bus. The monitor exists to catch exactly those bugs.

Tool as Truth

"Our Verilator runs never showed an x on that bus, so it is always initialised."

Verilator is a two-state simulator: unknowns are not modelled, so it cannot show one. Reset and X checks need a four-state simulator.

Source ASIC Point engine notes (Verilator 5.052 SVA probes), row "x/z values"

Learn It, Then Prove It