VLSI DV Interview Puzzles · All levels

Mailbox Consumer Blocks Forever

Collector thread blocks forever on mailbox get(). Producer thread silently died earlier. Find the control-flow interaction that causes permanent stall.

Puzzle

Difficulty: Medium · Puzzle 4 of 6 · Topic: Deadlock Scenario Puzzles: Objection and Phase Stalls

Collector thread blocks forever on mailbox get(). Producer thread silently died earlier. Find the control-flow interaction that causes permanent stall.

Code

systemverilog
mailbox #(pkt) mbx = new();

task run_phase(uvm_phase phase);
  fork
    begin : producer
      repeat (100) begin
        pkt p = new();
        build_pkt(p);
        mbx.put(p);
      end
    end
    begin : consumer
      forever begin
        pkt q;
        mbx.get(q); // blocks forever after producer dies
        process_pkt(q);
      end
    end
  join_any
  disable producer; // bug: kills producer early, consumer still infinite
endtask

Hint

join_any plus asymmetric disable is a common stall generator.

Step-by-step solution

diagram
1) Inspect fork control semantics and note consumer is unbounded forever loop.
2) Observe join_any returns as soon as either branch exits.
3) disable producer can terminate source while consumer continues blocking on empty mailbox.
4) Introduce termination protocol: sentinels, stop event, or bounded consumer loop.
5) Use try_get with wait/event/backoff if producer lifetime is dynamic.

Answer

Answer: Bug: fork control kills producer while consumer remains infinite blocking on mailbox.get. Fix: define explicit shutdown handshake or bounded loops so both threads terminate coherently.

Why candidates get it wrong

The stall is in TB orchestration, not mailbox implementation.

Interviewer follow-up

How would you redesign this with one supervisor thread owning both producer/consumer lifetime?

Related topics