Part 6 · Agents & Protocol IP · Intermediate

Sequence Routing: Request Ownership, IDs, and Response Return Paths

How sequencer preserves request ownership and returns responses to the correct sequence in concurrent traffic.

Ownership and routing model

In multi-sequence operation, the sequencer must preserve ownership boundaries: each request belongs to a source sequence context, and each response must route back to that context unless explicitly redirected.

diagram
[SEQ] routing invariants

1) req item has originating sequence context
2) driver processes granted req
3) rsp item maintains correlation key
4) sequencer returns rsp to correct sequence

if invariant 4 breaks, tests pass/fail nondeterministically
systemverilog
task body();
  my_item req, rsp;
  req = my_item::type_id::create("req");
  start_item(req);
  assert(req.randomize());
  finish_item(req);

  get_response(rsp); // should correspond to req ownership context
endtask
  • Treat response routing as correctness-critical in concurrent scenarios.

  • Keep correlation keys stable through driver transformations.

  • Avoid ad hoc global response queues when sequence ownership matters.


ID strategy and out-of-order responses

Protocols may return responses out of request order. Sequence routing should rely on stable IDs rather than temporal assumptions where out-of-order behavior is legal.

diagram
[SEQ][DRV] out-of-order safe model

request issue order:   req0 req1 req2
response return order: rsp1 rsp0 rsp2

sequencer/sequence logic must map by correlation id,
not by FIFO response arrival order
systemverilog
class tagged_seq extends uvm_sequence #(pkt_item);
  `uvm_object_utils(tagged_seq)
  int unsigned next_tag;

  task body();
    pkt_item req, rsp;
    repeat (8) begin
      req = pkt_item::type_id::create("req");
      start_item(req);
      req.tag = next_tag++;
      finish_item(req);
    end

    repeat (8) begin
      get_response(rsp);
      rsp_by_tag[rsp.tag] = rsp;
    end
  endtask
endclass
diagram
[SEQ] routing debug counters

req_sent_by_seq
rsp_received_by_seq
rsp_unmatched_count
duplicate_rsp_tag_count
max_rsp_latency_cycles

these expose ownership leaks quickly
  • Use correlation IDs when protocol allows out-of-order returns.

  • Track unmatched and duplicate response metrics in debug mode.

  • Design sequence response handling for concurrency, not single-stream assumptions.


Routing failure triage

When response handling fails, inspect boundaries in order: sequence send, sequencer grant context, driver correlation propagation, and sequence receive path.

diagram
[SEQ][UVM] routing triage order

step 1: verify request tag/seq context assignment
step 2: verify driver forwards/returns same tag
step 3: verify sequencer receives and routes response
step 4: verify sequence get_response logic accepts expected stream
step 5: verify no stale responses from previous phase/test
systemverilog
task assert_rsp_balance(my_seq s);
  if (s.req_count != s.rsp_count)
    `uvm_warning("RSP_BAL",
      $sformatf("%s req=%0d rsp=%0d", s.get_name(), s.req_count, s.rsp_count))
endtask
diagram
[SEQ][MON][AGT] routing vs observation

sequencer correctness:
  req/rsp ownership + mapping

monitor correctness:
  observed protocol behavior

both are needed:
  monitor can look correct while sequencer response ownership is broken

Key takeaways

  • Response routing correctness depends on preserved ownership context.

  • Out-of-order protocols require ID-based mapping, not FIFO assumptions.

  • Routing metrics make ownership bugs visible before functional fallout grows.

  • Triage should follow request->driver->sequencer->sequence boundaries in order.

Common pitfalls

  • Assuming response arrival order always matches request issue order.

  • Dropping correlation tags during driver adaptation layers.

  • Sharing global response queues across unrelated sequence contexts.

  • Ignoring req/rsp imbalance until end-of-test timeout failures.