← Design Verification Interviews

Interview Question · Code Reading

The Rise of an AND, or the AND of Two Rises

L1 JuniorL2 Mid-Levelsvasampled value functions

The Question

The interviewer asks

The rule should start a timer whenever a grant arrives while the block is enabled. en usually goes high a few cycles before gnt. What is wrong with this antecedent?

systemverilog
// "Start the timer when a grant arrives while enabled"
a_start: assert property (@(posedge clk)
           $rose(gnt) && $rose(en) |-> ##1 timer_on) else errors++;
Reveal the Model Answer

$rose(gnt) && $rose(en) needs both signals to rise at the same edge. A grant that arrives while en is already high never starts the check. The event the spec describes is the condition gnt && en becoming true, which is $rose(gnt && en). A sampled value function applies to its whole argument expression, so where you put the parentheses changes the event.

Two Rises, or the Rise of an AND
012345edge (ns)51525354555engnt$rose(gnt) && $rose(en)$rose(gnt && en)grant while enabled: only the second form sees itboth rise together: both forms see it

One column per rising edge. Measured: the twin sees only the start at 45; the fix sees starts at 25 and 45.

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Junior)

A good junior answer finds the case where en rises first. It shows that the antecedent never matches there.

Cross-Questions

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

WhyWhat IfProve ItBreak ItCompare

  1. The Rise of an AND, or the AND of Two Rises
  2. WhyWhy the Function Samples the Whole ExpressionL2 Mid-Level

    Why does $rose(a && b) mean the AND became true, rather than something about a and b separately?

    Reveal the Model Answer

    The argument is an expression, and the function keeps a history of that expression's sampled value, one entry per clock tick. It compares the expression's value now with its value at the previous tick. So it detects the moment the combined condition changes, whatever each operand did.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "$rose distributes over && like a logic operator."

    It is not a Boolean operator. It works on the value history of its argument, and that history is not the AND of the operands' histories.

    Source Mehta, SystemVerilog Assertions and Functional Coverage (3rd ed.), ch. 7 (PDF p113-119)

  3. What IfRose and Past on a Gated ClockL2 Mid-Level

    What if the property clock is gated off for ten cycles? What does $rose compare against?

    Reveal the Model Answer

    $rose compares with the value at the previous tick of its own clock, not the previous time unit. If the clock stops, the previous tick is the last edge before the stop. A pulse that comes and goes during the stop is never seen. Use a free-running clock for checks that must see every change.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "$past(x) means the value one clock period ago."

    It means one tick of the property clock ago. A gated or slower clock makes that much longer.

    Source IEEE 1800-2017 §16.9.3

  4. CompareAn Edge of the Condition vs the Condition ItselfL2 Mid-Level

    Compare $rose(gnt && en) |-> ##1 timer_on with gnt && en |-> ##1 timer_on.

    Reveal the Model Answer

    The edge form starts one attempt when the condition becomes true and says nothing about the following cycles. The level form starts an attempt at every edge the condition holds, so it also demands timer_on after each of those cycles. Choose by the spec: "starts when" is an edge, "runs while" is a level.

    Edge form: $rose(gnt && en)Level form: gnt && en
    Starts attemptsOnce, when the condition becomes trueAt every edge the condition holds
    Demands timer_onAfter the first cycle onlyAfter each of those cycles
    Spec wording"starts when""runs while"

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "The level form is stricter, so it always catches more bugs."

    It catches different bugs and also fails correct designs whose timer is one-shot. Stricter than the spec is wrong, not safer.

    Source IEEE 1800-2017 §16.12.7

  5. What IfA Gated PastL2 Mid-Level

    Asked if they move on to $past with an enable

    What if the pipeline only advances when en is high? What does $past(din, 1, en) return?

    Reveal the Model Answer

    The third argument gates the clock. $past(din, 1, en) returns din from the most recent earlier tick where en was true, skipping stalled ticks. That matches a pipeline register with an enable. Verilator 5.052 rejects the gating argument at compile time, so on that engine keep a shadow register updated under en instead.

    $past(din, 1, en) skips the ticks where en is low
    01234edge12345endinabcdegated past-adlast enabled tick before 4 was 1: returns a

    Only ticks with en high advance the gated history.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "The gating argument makes $past return x when en is low."

    It does not mask the result; it decides which earlier ticks count as history.

    Source IEEE 1800-2017 §16.9.3

  6. Break ItSampling an Expression That Calls a FunctionL2 Mid-LevelL3 Senior

    A colleague writes $rose(fifo_has_space(count)), where the function reads a class object. What can break?

    Reveal the Model Answer

    The standard bans output and ref arguments for functions in assertion expressions. It also expects them to be automatic, with no side effects. A function that reads a class object hides its real inputs from the assertion. Those inputs are not sampled with the rest of the expression. Pass every input as an argument, or compute the condition into a design-side variable that the assertion samples.

    Self-Check

    Tick each key point you covered in your answer.

    Missed Corner

    "Any function that compiles is fine in an assertion."

    Output and ref arguments are illegal there, and side effects would run once per attempt. State read behind the arguments is the subtle case: the verdict then depends on more than the sampled operands.

    Source IEEE 1800-2017 §16.6

  7. Prove ItSolve 6.6.7: Count the BeatsSimulator-graded

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

    Open Problem 6.6.7

What People Get Wrong

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

Misconception

"$rose(gnt) && $rose(en) is the moment gnt && en becomes true."

That form needs two simultaneous rises. In the twin the grant at 25 arrives with en already high and is missed; $rose(gnt && en) sees both starts.

Run It

Two starts: a grant while enabled (25), and grant and enable together (45).

RUNVerilator · simulator service
Edit the code, then run it
Expected: t=45 start seen starts seen: 1 of 2 FAIL: the AND of two rises needs both to rise at once, so the grant at 25 was missed
See the Fix
module tb;
  logic clk = 0, gnt = 0, en = 0;
  int starts = 0;
  always #5 clk = ~clk;
  // The fix: $rose of the combined condition.
  a_start: assert property (@(posedge clk) !($rose(gnt && en)))
    else begin starts++; $display("t=%0t start seen", $time); end
  initial begin
    @(negedge clk) en = 1;              // enable first
    @(negedge clk) gnt = 1;             // grant while enabled: a start (25)
    @(negedge clk) begin gnt = 0; en = 0; end
    @(negedge clk) begin gnt = 1; en = 1; end   // both together: a start (45)
    @(negedge clk) begin gnt = 0; en = 0; end
    repeat (2) @(negedge clk);
    $display("starts seen: %0d of 2", starts);
    if (starts == 2) $display("PASS: $rose(gnt && en) saw both starts");
    $finish;
  end
endmodule

Prints: t=25 start seen t=45 start seen starts seen: 2 of 2 PASS: $rose(gnt && en) saw both starts

Missed Corner

"Both forms pass the directed test, so they are equivalent."

A test that raises both signals together cannot tell them apart. The difference only appears when one signal leads the other, which the twin includes.

Source IEEE 1800-2017 §16.9.3

Learn It, Then Prove It