← Design Verification Interviews

Interview Question · Concept

Callbacks vs Factory Overrides for Error Injection

L2 Mid-Leveluvmcallbacksfactory

The Question

The interviewer asks

You must corrupt the parity on chosen beats from one test, without changing the driver for anyone else. Do you use a callback or a factory override?

Reveal the Model Answer

Both work without editing the driver. A factory override swaps in a subclass, so the test can change any virtual method, but only one subclass per instance. A callback runs code at hooks the driver author placed, and several callbacks can stack on one instance. Use a callback when the driver has the hook you need. Use an override when you must change behaviour the author did not expose.

One Driver, a List of Callbacks, Two HooksOne driver instance with two hooks. Solid arrows are calls; the list holds callback handles in calling order.
One driver, a list of callbacks, two hooksOne driver instance with two hooks. Solid arrows are calls; the list holds callback handles in calling order. registers Test add(port_b.drv,perr); add(null, cov) facade port_b.drv pre_drive andpost_drive hooks queue Callback list perr, then cov callback perr pre_drive: flips paron item 2 callback cov post_drive: countsbeats taken interface lane_if pins valid, x, par additeratecall 1call 2drives the beat
  1. Register

    In connect_phase the test adds perr to this driver only and cov to every lane_driver. The driver's code does not change.

    Follow the calls, values and waits
    1. data perr handle: Test → Callback list
    2. data cov handle: Test → Callback list
  2. pre_drive20 ns (illustrative)

    At 20 ns the driver has built the beat for item 2 (x = 32, par = 1). uvm_do_callbacks walks the list; perr flips par to 0. cov has no pre_drive, so the base method does nothing.

    Follow the calls, values and waits
    1. call pre_drive(item 2): port_b.drv → Callback list
    2. call pre_drive(item 2): Callback list → perr
    3. return beat x=32, par=0: perr → Callback list
  3. Drive20 ns (illustrative)

    The pre_drive walk returns, and the driver itself puts the edited beat on the pins and waits for the lane to take it.

    Follow the calls, values and waits
    1. data beat x=32, par=0: port_b.drv → lane_if pins
    2. Waiting: port_b.drv — waiting for an edge with ready
  4. post_drive45 ns (illustrative)

    The lane takes the beat at 45 ns. After that edge with ready, the same walk calls cov.post_drive, which records one bad-parity beat for port_b.

    Follow the calls, values and waits
    1. call post_drive(item 2): port_b.drv → Callback list
    2. call post_drive(item 2): Callback list → cov
    3. Released: port_b.drv
Read the diagram as text
  • Test: add(port_b.drv, perr); add(null, cov)
  • port_b.drv: pre_drive and post_drive hooks
  • Callback list: perr, then cov
  • perr: pre_drive: flips par on item 2
  • cov: post_drive: counts beats taken
  • lane_if pins: valid, x, par
  • Test → Callback list: add
  • port_b.drv → Callback list: iterate
  • Callback list → perr: call 1
  • Callback list → cov: call 2
  • port_b.drv → lane_if pins: drives the beat

The driver owns the hook points and their arguments; tests own the list. Calls run in list order.

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Mid-Level)

A good mid-level answer names the cost of each choice. Callbacks need hooks that the author designed in, and an override allows only one subclass at a time.

Cross-Questions

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

WhyWhat IfProve ItCompareScale It

  1. Callbacks vs Factory Overrides for Error Injection
  2. WhyWhy Callbacks Use a Typed PoolL2 Mid-Level

    Why are UVM callbacks added through a typed pool, uvm_callbacks #(T, CB), rather than a plain list?

    Reveal the Model Answer

    The pool checks at compile time that the callback type fits that component type. The component must also declare the pair with uvm_register_cb, or adding a callback reports a warning. The pool can add a callback to one instance or to every instance of the type. The driver then runs only the callbacks registered for itself.

    Self-Check

    Tick each key point you covered in your answer.

    Missed Corner

    "Any callback can be added to any component."

    Without uvm_register_cb for that pair, uvm-core reports CBUNREG and the callback is not used as intended.

    Source uvm-core 2020.3.1 (IEEE 1800.2 library) source, base/uvm_callback.svh (CBUNREG check)

  3. What IfTwo Callbacks Changing One ItemL2 Mid-Level

    What if two callbacks on the same driver both change the item? Which runs first?

    Reveal the Model Answer

    They run in the order they were added, unless one is added with UVM_PREPEND. Both get the same item, so the second sees the first's change. Two error injections on one item can even cancel each other. If the order matters, add them in one place, such as the test.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "Each callback gets its own copy of the item."

    They receive the same handle. A later callback sees, and can undo, an earlier change.

    Source uvm-core 2020.3.1 (IEEE 1800.2 library) source, base/uvm_callback.svh, add (ordering UVM_APPEND)

  4. CompareAn Error Field in the Item vs a Driver CallbackL2 Mid-Level

    Compare injecting the error in the driver with an error field in the sequence item.

    Reveal the Model Answer

    An error field, such as bad_parity, lets the sequence choose which beats to corrupt, and it appears in the item's print. The driver must already understand the field. A driver callback needs no change to the item, but the choice of beats then lives in the callback. Prefer the item field when you own the agent.

    Self-Check

    Tick each key point you covered in your answer.

  5. Prove ItSolve U12.1.1: Inject a Bad Check on One Lane, on Chosen BeatsSimulator-graded

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

    Open Problem U12.1.1

  6. Scale ItError Injection in Closed VIPL3 Senior

    Scale it: the VIP is encrypted and has no hook where you need one. What now?

    Reveal the Model Answer

    You cannot add a callback where no hook exists, and you cannot safely override methods you cannot read. Ask the vendor for the hook, and check whether the VIP already has an error knob in its config or items. Meanwhile, inject the error between the driver and the DUT with a small module on the interface. Record the gap in the test plan.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Senior)

    A good senior answer first checks the VIP's own error settings. Then it proposes a small module between the driver and the DUT, and reports the gap to the vendor.

What People Get Wrong

Common wrong answers and why they fail.

Misconception

"A callback can change any behaviour of the driver."

It acts only where the driver calls uvm_do_callbacks. If no hook sits before the parity is driven, no callback can change the parity.

Source Accellera, UVM 1.1 User's Guide, §6.3 callbacks (PDF p143)

Half-Truth

"Factory overrides are always cleaner."

Two independent features, say error injection and an extra coverage hook, each need a subclass. Combining them needs a third subclass, while two callbacks simply stack.

Wrong Altitude

Adds a global flag that the shared driver checks for error injection.

That edits the driver for every user and puts one test's intent into shared code. Both callbacks and overrides keep the change inside the test.

Learn It, Then Prove It