← Design Verification Interviews

Interview Question · Concept

The Event Nobody Heard

L1 JuniorL2 Mid-Levelsystemverilogeventssynchronisation

The Question

The interviewer asks

A producer triggers -> done at time 0 and a consumer waits with @(done), also at time 0. Sometimes the consumer hangs forever. Why, and how do you make it robust?

Reveal the Model Answer

An event trigger wakes only processes already waiting at that moment, and two processes at time 0 run in an unspecified order. If the producer runs first, the trigger is lost and @(done) waits for one that never comes. Wait with wait (done.triggered), which stays true for the rest of the time step. When the message must last longer, use a flag or a mailbox.

The Trigger Fires Just Before Anyone Is Listening
01234567drain_done (trigger)monitordraintriggeridlescoreboardbusybusy, then @blockedreport printedtrigger, then @ in the same time step
  1. Cycle 0

    The monitor is still draining, and the scoreboard is busy with its last checks.

  2. Cycle 3

    In one time step, the monitor triggers drain_done first. Then the scoreboard reaches @(drain_done), after the trigger is over.

  3. Cycle 4

    The scoreboard is blocked, waiting for a second trigger. The monitor is idle and never sends one.

  4. Cycle 7

    No report is printed. The test hangs until the global timeout.

A trigger has no width: it is over before the scoreboard starts to wait.

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Junior)

A good junior answer explains the ordering race between the two processes. It proposes wait (done.triggered) as the fix.

Cross-Questions

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

WhyWhat IfProve ItCompare

  1. The Event Nobody Heard
  2. WhyWhy Events Have No MemoryL1 Junior

    Why are named events designed as momentary edges instead of flags?

    Reveal the Model Answer

    An event means "something happened now", like a clock edge. Every process waiting at that moment wakes together, and nothing has to clear the event. A flag would need someone to decide when to reset it, and a reset race is just as hard. When the information must persist, a variable, a semaphore or a mailbox is the right tool.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "Events are queued like mailbox messages."

    Triggers are not counted or stored. Three triggers before anyone waits are the same as none.

    Source IEEE 1800-2017 §15.5

  3. WhyWhy Triggered Clears at the End of the Time StepL1 JuniorL2 Mid-Level

    Why does the triggered property reset at the end of the time step instead of staying set?

    Reveal the Model Answer

    triggered exists only to remove the race within one time step. If it stayed set, a later wait would wake on an old trigger. The event would then be a flag, and someone would have to clear it. For facts that must last, use a variable or a counter.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "wait (e.triggered) works across clock cycles."

    It is true only until the end of the trigger's time step. A waiter that arrives a cycle later blocks forever.

    Source IEEE 1800-2017 §15.5.3

  4. CompareEvent, Semaphore or MailboxL1 JuniorL2 Mid-Level

    Compare a named event, a semaphore and a mailbox for telling a checker that a transaction is ready.

    Reveal the Model Answer

    An event signals a moment and carries nothing, so it suits "start now" among processes that are already waiting. A semaphore counts keys, which suits sharing a resource, such as one bus between two drivers. A mailbox queues the transaction itself, so a slow checker loses nothing; it is the usual choice for passing data between components.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Use a semaphore with one key as an event."

    A key put back before anyone waits is remembered, unlike an event, and keys are not tied to data. It works by accident and confuses the next reader.

    Source IEEE 1800-2017 §15.3

  5. Prove ItSolve 3.6.1: Protected Shared CounterSimulator-graded

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

    Open Problem 3.6.1

  6. Prove ItSolve 3.4.1: Persistent Initialization FlagSimulator-graded

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

    Open Problem 3.4.1

  7. What IfWhen Triggered Is Not EnoughL2 Mid-Level

    Asked if they propose .triggered as the general fix

    What if the consumer starts waiting one clock cycle after the producer triggers the event?

    Reveal the Model Answer

    wait (done.triggered) misses it too, because the triggered state is cleared at the end of the time step. When the waiter can arrive later, record the fact in something persistent. Set a bit and wait on it, put a message in a mailbox, or use a semaphore key.

    Three Waiters After One TriggerA monitor sets a flag and triggers an event. Three waiters arrive after the trigger, in different ways. Arrows from the monitor are what it writes; arrows into a waiter show what that waiter watches.
    Three waiters after one triggerA monitor sets a flag and triggers an event. Three waiters arrive after the trigger, in different ways. Arrows from the monitor are what it writes; arrows into a waiter show what that waiter watches. process Monitor at t=30: total, flag,trigger event drain_done event: keeps no record variable drained bit: stays 1 process Waiter 1 @(drain_done) process Waiter 2 wait(drain_done.triggered) process Waiter 3 wait (drained), att=40 -> drain_donedrained = 1wakes a waiteralready at @triggeredvalue
    1. The monitor publishest=30 (illustrative)

      The monitor sets total to 12, sets drained, then triggers drain_done. No waiter is at its wait yet: each of the first two ran a #0 delay, which made it step aside until the monitor had run.

      Follow the calls, values and waits
      1. data 1: Monitor → drained
      2. data trigger: Monitor → drain_done
    2. Waiter 1 arrives after the triggert=30 (illustrative)

      Waiter 1 reaches @(drain_done) when the trigger is already over. It waits for the next trigger, which never comes.

      Follow the calls, values and waits
      1. Waiting: Waiter 1 — blocked at @
    3. Waiter 2 finds triggered sett=30 (illustrative)

      Waiter 2 also arrives after the trigger, but triggered is 1 until this time step ends. Its wait returns at once and it prints total=12.

      Follow the calls, values and waits
      1. data triggered = 1: drain_done → Waiter 2
    4. Waiter 3 arrives latet=40 (illustrative)

      At t=40, triggered reads 0 again. Waiter 3 waits on drained, which is still 1, so it returns at once and prints total=12.

      Follow the calls, values and waits
      1. data drained = 1: drained → Waiter 3
    5. The end of the runt=100 (illustrative)

      Waiter 1 is still blocked at its @, as the last line of the log reports.

    Read the diagram as text
    • Monitor: at t=30: total, flag, trigger
    • drain_done: event: keeps no record
    • drained: bit: stays 1
    • Waiter 1: @(drain_done)
    • Waiter 2: wait (drain_done.triggered)
    • Waiter 3: wait (drained), at t=40
    • Monitor → drain_done: -> drain_done
    • Monitor → drained: drained = 1
    • drain_done → Waiter 1: wakes a waiter already at @
    • drain_done → Waiter 2: triggered
    • drained → Waiter 3: value

    An event reaches only the processes already waiting. A flag reaches anyone who looks later.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    ".triggered fixes every event race."

    It covers only the same-time-step ordering race. Any gap in time needs a persistent signal.

    Source IEEE 1800-2017 §15.5.3

What People Get Wrong

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

Misconception

"An event remembers that it was triggered until somebody waits."

A trigger is instantaneous; a waiter that arrives later misses it. The twin triggers first and the waiter never wakes.

Run It

A producer and a consumer starting at time 0.

RUNVerilator · simulator service
Edit the code, then run it
Expected: woke=0 FAIL: the trigger ran before the waiter reached @(done), so the event was missed

Tool as Truth

"It works in our simulator, so the order is fine."

The order of two initial blocks at time 0 is not specified. The same code can hang after a tool upgrade or a file reorder.

Source IEEE 1800-2017 §4.7

Spec Misquote

".triggered keeps the event set until the end of the test."

The triggered state is cleared at the end of the time step in which the event fired.

Source IEEE 1800-2017 §15.5.3

Learn It, Then Prove It