Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • Start Here4
  • UVM Foundations14
  • UVM Phases & Simulation Lifecycle26
  • Factory & Configuration15
  • Transaction-Level Modeling (TLM)13
  • UVM Sequences & Stimulus21
  • UVM Agents & Protocol VIP21
  • Environment & Test Classes11
  • Checking & Coverage in UVM21
  • UVM Register Abstraction Layer (RAL)22
  • Advanced UVM in Practice13
  • Debug & Regression10
  • Coding Practice47
  • Verification in Industry Practice10
  • Senior Prep: Architecture, Leadership and Interviews32
    • Verification Architecture and Planning
    • UVM with SVA and Formal
    • Leadership and Senior Judgment
    • Interview Bank
      • Concept Round: Phases, Objections and End of Test
      • Concept Round: Factory and config_db
      • Concept Round: TLM and Analysis
      • Concept Round: Sequences, Sequencers and Drivers
      • Concept Round: Agents, Drivers and Monitors
      • Concept Round: Register Layer and Checking
      • Closure and Sign-off Questions
      • Behavioural Round
      • Coding Round: Whiteboard Drills
      • Debug Round: Find the Bug in This Log
      • Architecture Round: Design the Verification
      • High-Frequency Question Index
      • The Senior DV Interview Loop
Loading lesson

‹Interview Bank
  1. Topics
  2. UVM Verification
  3. Senior Prep: Architecture, Leadership and Interviews
  4. Interview Bank
  5. Concept Round: TLM and Analysis

Part 13 · Senior Prep · Intermediate

Concept Round: TLM and Analysis

Ten high-frequency questions on ports, exports and imps, connection rules, unconnected ports, analysis write order, analysis FIFOs, pass-by-handle and TLM 2.0, with weak and senior answers.

On this page

    TLM questions look like vocabulary tests, which is why mid-level candidates relax. Then the follow-up arrives: "so what happens if nobody connects it?", or "in what order do the subscribers see the write?". Those have exact answers in the library, and the wrong ones cause the silent failures seniors are hired to prevent.

    Answer in terms of control flow and ownership: who calls whom, who owns the object, what is checked at elaboration and what is never checked. Use the DMA bench's analysis network (three monitors feeding a scoreboard, a predictor, a comparator, coverage and a watchdog) as your example.

    The questions

    Port, export, imp: what is the difference?

    Interview

    Weak answer: A port sends data and an export receives it.

    Strong answer: They describe control flow, not data direction. A port requires an interface: its owner calls the method. An imp provides it: the component that owns the imp implements the method. An export forwards an imp up the hierarchy so a parent can offer its child's implementation. A get port pulls data in, which is why "port sends" is wrong.

    Follow-up: “Who implements put on a uvm_tlm_fifo?” The FIFO. Its put_export and get_peek_export are backed by its own implementation, so producer and consumer both hold ports.

    Home lesson: Initiator and target roles

    Which way do hierarchical connections go?

    Interview

    Weak answer: Either way works as long as both ends are connected.

    Strong answer: Port to port goes child to parent: child.port.connect(parent.port). Export to export goes parent to child: parent.export.connect(child.export). A port finally connects to an export or an imp. Connections are made in connect_phase, after every component exists.

    Follow-up: “What happens if you write export.connect(port)?” An error at the call: Cannot connect exports to ports. Try calling port.connect(export) instead. Calling connect on an imp is an error too.

    Home lesson: Connecting through the hierarchy

    A put port is never connected. When do you find out? And an analysis port?

    Interview

    Weak answer: Nothing happens until you call it; then you get a null-handle crash.

    Strong answer: A non-analysis port has a minimum of one connection, so resolve_bindings reports an error at end of elaboration, before time 0. An analysis port with no subscribers is legal, by design, so a forgotten analysis connect is silent: the scoreboard receives nothing and the test passes with zero compares. That is the case to guard against, with a scoreboard that fails when it compared nothing.

    Follow-up: “Can you check analysis connections explicitly?” Yes: size() on the port returns its connection count, so a check in end_of_elaboration can insist the monitor has subscribers.

    Home lesson: Channels and cardinality

    A monitor's analysis port feeds the scoreboard and coverage. In what order do they see the write?

    Interview

    Weak answer: In the order they were connected.

    Strong answer: In alphabetical order of the subscribers' full names, because the imp list is an associative array keyed by name. Rename a component and the order changes. So never depend on it: if coverage needs the scoreboard's verdict for the same transaction, have the scoreboard publish its own result, or sequence the work through FIFOs. Connecting a second subscriber never overwrites the first; an analysis port fans out to all of them.

    Follow-up: “Can one imp take many ports?” Yes. An analysis export or imp accepts many ports; the DMA bench's dma_activity_watchdog subscribes to all three monitors.

    Home lesson: Analysis broadcast

    Your subscriber needs to wait for the matching expected item inside write(). Can it?

    Interview

    Weak answer: Yes, write() can wait until the other side arrives.

    Strong answer: No. write() is a function, so it cannot consume time; every subscriber runs inside the monitor's call, in the same time step. A subscriber that must wait or correlate puts the item in a uvm_tlm_analysis_fifo and drains it from its own run_phase. That FIFO is unbounded, so a stalled consumer grows memory without limit; a plain uvm_tlm_fifo defaults to depth 1 and blocks the producer instead.

    Follow-up: “Why is write() a function at all?” So a monitor can broadcast without being slowed or blocked by any subscriber. Heavy work in write() still slows everyone, because it runs synchronously.

    Home lesson: FIFOs and TLM debug

    How do two analysis streams reach one scoreboard?

    Interview

    Weak answer: Declare two uvm_analysis_imp members.

    Strong answer: Two plain imps would both call the same write(). Either declare suffixed imps with the uvm_analysis_imp_decl macro, which generates write_<suffix> methods, or use exports into analysis FIFOs and match in run_phase. Make the write_* methods virtual: on the DMA bench, a factory-overridden scoreboard's non-virtual write_* never ran, because the imp calls through the base class type.

    Follow-up: “Which do you prefer?” FIFOs when matching needs time or ordering across streams; suffixed imps for immediate work such as counters and coverage.

    Home lesson: Two analysis imps

    Every entry in your scoreboard queue shows the same data. What happened?

    Interview

    Weak answer: TLM copies the transaction, so it must be a scoreboard bug.

    Strong answer: TLM passes handles, not copies. The monitor reused one item handle and refilled it per transfer, so the queue holds the same object many times, all showing the last value. Monitors broadcast a fresh object per transaction (create a new item, or clone before write). Any subscriber that modifies an item clones it first, which is exactly what the DMA bench's truncating driver does with the item it is handed.

    Follow-up: “Publisher or subscriber: who clones?” The publisher creates a fresh object per transfer; a subscriber clones only if it modifies. Cloning in every subscriber as a habit costs time and hides the real bug.

    Home lesson: Passive sampling and fresh objects

    Blocking or nonblocking, get or peek: what do the TLM 1 methods promise?

    Interview

    Weak answer: Nonblocking is just a faster version of blocking.

    Strong answer: Blocking put/get/peek are tasks and may wait. try_put, try_get, can_put and friends are functions: they return at once with a success bit. get removes the item; peek returns it and leaves it. transport sends a request and returns the response in one call. The driver-sequencer link is its own pull interface (get_next_item / item_done), not a plain get port.

    Follow-up: “Why is seq_item_port not a plain get port?” The sequence must know when the item is finished (item_done) and where to route a response, which a plain get cannot express.

    Home lesson: put, get and transport

    TLM 2.0: when do you use b_transport and when nb_transport?

    Interview

    Weak answer: TLM 2.0 is only for SystemC.

    Strong answer: Sockets carry a uvm_tlm_generic_payload. b_transport(t, delay) completes the transaction in one blocking call, with the delay argument allowing temporal decoupling. nb_transport_fw/_bw model a pipelined protocol in phases (BEGIN_REQ, END_REQ, BEGIN_RESP, END_RESP) and return ACCEPTED, UPDATED or COMPLETED. In UVM benches TLM 2.0 mostly appears at a SystemC or model boundary; agents keep using TLM 1 analysis ports.

    Follow-up: “Who owns the payload?” The initiator creates it; the target fills in the response status and data in place. Do not keep a reference after the transaction completes.

    Follow-up: “Protocol-specific fields?” Generic payload extensions, not a subclass, so the payload stays interoperable.

    Home lesson: Nonblocking transport

    Why analysis ports instead of having the monitor call the scoreboard directly?

    Interview

    Weak answer: Because it is the UVM way.

    Strong answer: Decoupling. The monitor knows nothing about its subscribers, and zero subscribers is legal, so the same agent works passive at subsystem level. The DMA bench proves it: dma_subsys_env reuses dma_env twice unchanged, makes dma1's input agent passive, and adds an end-to-end checker that subscribes to existing monitors. Adding coverage or a watchdog is a connect, not an edit.

    Follow-up: “What does that decoupling cost?” One synchronous function call per subscriber per transaction, and no ordering guarantee between subscribers.

    Home lesson: Analysis connectivity patterns

    Rapid fire

    Check yourself A coverage collector named sb_cov reads the scoreboard's last verdict inside its write(). A refactor renames it cov, and it starts sampling the previous transaction's verdict. Why?

    Analysis subscribers are called in alphabetical order of full name. env.sb sorted before env.sb_cov, so the scoreboard ran first; env.cov sorts before env.sb, so coverage now runs first and sees the old verdict. The real bug is depending on the order at all: the scoreboard should publish its verdict on its own analysis port.

    Check yourself A team connects the out agent's monitor port to the same scoreboard imp twice by accident. Is write() now called twice per transaction?

    No. A port records its providers keyed by the provider's full name, so connecting the same imp again stores the same single entry, silently. Connecting a different subscriber adds to the list and never overwrites one. A connect made at or after end of elaboration is ignored with a Late Connection warning.

    Next: Concept Round: Sequences, Sequencers and Drivers: the interrupt handler needs the bus now; lock or grab?

    Previous

    270 / 280

    Next: Concept Round: Sequences, Sequencers and Drivers

    Up next

    Up nextConcept Round: Sequences, Sequencers and Drivers

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Concept Round: Phases, Objections and End of Test
    • Concept Round: Agents, Drivers and Monitors
    • Concept Round: Register Layer and Checking