Part 4 · TLM & Analysis · Intermediate

Analysis vs put/get: Broadcast Observability vs Point-to-Point Flow

Decision framework for choosing analysis write() broadcast or put/get/transport point-to-point channels based on ownership, flow control, and verification intent.

Core semantic difference

Use analysis when one producer publishes passive observations to one or many consumers. Use put/get when components exchange transactions in an active point-to-point flow with control semantics.

diagram
[TLM] semantic contrast

 analysis_port.write(tr):
   - broadcast style
   - one-way publish
   - no protocol-level backpressure handshake
   - ideal for monitor/check/coverage pipelines

 put/get:
   - point-to-point request/consume
   - blocking/non-blocking semantics available
   - flow/control relationship explicit
   - ideal for active data movement between components
diagram
[MON][CHECK] role alignment

 passive monitor output  -> analysis
 command producer/worker -> put/get or seq/driver flow
 buffering/decoupling    -> tlm_fifo or analysis_fifo depending direction
  • Analysis is publish/observe; put/get is exchange/consume.

  • Choose by interaction semantics, not personal style preference.

  • Wrong channel choice creates fragile or over-coupled architectures.


Decision matrix for real environments

Use a short decision matrix in reviews so teams converge quickly on the right TLM primitive.

diagram
Question                                             Prefer
──────────────────────────────────────────────────────────────────────────────
Need one producer to feed N checkers/coverage?             analysis
Need consumer to control pacing/availability?              put/get
Path is passive observation from monitor?                  analysis
Path is active work dispatch to a worker component?        put/get
Need request/response coupling?                            put/get/transport
Need broad telemetry fan-out with loose coupling?          analysis
diagram
[TLM] quick chooser

 If you say:
   "I observed something, many blocks should know"
      -> analysis

 If you say:
   "I need someone to take this work item and maybe block"
      -> put/get
diagram
[CHECK] architecture review prompts

 1) Is this path active command or passive observation?
 2) Is one-to-many fan-out required?
 3) Should producer ever wait for consumer readiness?
 4) Are we accidentally using one primitive to emulate another?
  • Decision clarity early avoids refactors later.

  • Review language around passive vs active ownership to pick correctly.

  • Do not force flow-control semantics onto analysis paths.


Hybrid pattern: analysis for observe, put/get for work

Many designs use both patterns together: monitor broadcasts observations through analysis, while a checker dispatcher sends selected items to workers via put/get.

diagram
[MON][TLM][CHECK] hybrid architecture

 [MON] monitor.ap.write(obs_tr)
    ├─► scoreboard ingest/check
    ├─► coverage ingest/sample
    └─► dispatcher subscriber
            └─ put_port.put(work_item) ─► worker

 analysis handles observability fan-out
 put/get handles controlled work handoff
systemverilog
class check_dispatcher extends uvm_subscriber #(obs_txn);
  `uvm_component_utils(check_dispatcher)
  uvm_blocking_put_port #(work_txn) work_p;

  function new(string name, uvm_component parent);
    super.new(name, parent);
    work_p = new("work_p", this);
  endfunction

  function void write(obs_txn t);
    work_txn w = obs_to_work(t);
    work_q.push_back(w); // quick ingest
  endfunction

  task run_phase(uvm_phase phase);
    forever begin
      wait (work_q.size() > 0);
      work_p.put(work_q.pop_front()); // controlled handoff path
    end
  endtask
endclass
diagram
[TLM] hybrid benefit

 keep monitor path passive and scalable
 keep worker path explicit and flow-controlled
 avoid overloading analysis write() with command semantics
  • Using both primitives is normal when concerns differ.

  • Do not push active work control directly into monitor write() path.

  • Bridge patterns should ingest quickly, then dispatch deliberately.


Walkthrough: avoiding common misuses

Common misuse: trying to send commands to drivers through analysis because monitor wiring already exists. This couples passive observation and active control in fragile ways.

diagram
[CHECK] misuse example

 bad:
   monitor.ap -> component.write() -> directly drives DUT behavior

 why bad:
   passive observation channel now changes DUT stimulus path
   difficult to reason about cause/effect and ordering
diagram
[TLM] corrected split

 observation:
   monitor.ap -> scoreboards/coverage/predictor

 command:
   sequence/dispatcher -> put/get or sequencer-driver path

 clean ownership boundaries improve debuggability
systemverilog
function void architecture_sanity();
  if (monitor_ap_connected_to_driver_control)
    `uvm_warning("ARCH",
      "analysis channel appears to drive active stimulus path")
endfunction

Key takeaways

  • Choose analysis for passive one-to-many observability and put/get for active controlled exchange.

  • Flow-control needs are the fastest discriminator between these TLM styles.

  • Hybrid architectures are strong when each path keeps clear ownership boundaries.

  • Avoid using analysis channels to carry active stimulus control logic.

Common pitfalls

  • Forcing put/get behavior into analysis write() consumers.

  • Routing active driver control through passive monitor broadcast paths.

  • Skipping a decision matrix and choosing primitives inconsistently across agents.

  • Building monolithic components that both observe and command through one channel.