Skip to content

UVM

Transaction Reconstruction

How a monitor deserializes pin-level activity back into a transaction — the inverse of the driver's serialization: collecting each field at the protocol cycle it appears, across the transaction's full multi-cycle duration, and emitting only when complete.

Monitors · Module 13 · Page 13.2

The Engineering Problem

Passive observation (Module 13.1) established what a monitor does: it observes the pins and reconstructs what it sees into transactions, passively and independently. This chapter is the how of that reconstruction. The driver serialized a transaction onto the bus — it took a single transaction object and spread it across multiple cycles (address this cycle, data later, qualified by handshakes, Module 12.2). The monitor must do the exact inverse: take the multi-cycle pin activity and re-assemble it into a single transaction object. The hard part is that a transaction is not a single cycle — it has phases: the address appears at the address phase, the data appears (possibly several cycles) later, a burst spreads data across many beats. The monitor must collect each field at the cycle it actually appears, across the transaction's full duration, and emit the transaction only when it's complete. Sample everything in one cycle and you capture an address that's valid but data that isn't — a wrong transaction from correct pins.

Transaction reconstruction is the process by which the monitor deserializes pin-level activity back into a transaction. Where the driver unpacked a transaction into a timed sequence of pin values (serialization), the monitor re-packs that timed sequence back into a transaction (deserialization) — and to do it correctly, it must follow the protocol's framing: know which cycle each field appears on, collect it there, and assemble the complete transaction across the transaction's whole lifetime. This chapter is reconstruction's mechanics: the inverse-of-serialization model, the multi-cycle collection it requires, completeness and correctness, and the framing bug that produces a wrong transaction from a correct bus.

How does a monitor reconstruct a transaction from pin-level activity — collecting each field at the protocol cycle it appears, across the transaction's full multi-cycle duration, and emitting only when complete — as the inverse of the driver's serialization?

Motivation — why reconstruction is more than a single sample

Reconstruction looks like "read the pins into a transaction," but the timing makes it a genuine process. The reasons it's non-trivial:

  • A transaction is multi-cycle. The driver spread the transaction across time — address at the address phase, data at the data phase (often later), a burst across many beats. So the fields don't all exist on the bus at once; the monitor must collect them across cycles.
  • Each field has a valid cycle. A field is only meaningful on the bus during its phase (qualified by the handshake / valid). Sample data before its phase and you capture a stale or X value. The monitor must sample each field when it's valid, not all at one moment.
  • Reconstruction is the inverse of serialization, so it needs the same protocol knowledge. The driver knew the framing to serialize (what to drive when, Module 12.2); the monitor needs the same framing to deserialize (what to sample when). Reconstruction is protocol-specific by nature.
  • Completeness matters — emit only when whole. The scoreboard and coverage need all the fields. Emit a transaction before the last field arrives and you broadcast an incomplete transaction (a default/garbage field) → a false mismatch. The monitor must wait until the transaction is complete, then emit once.
  • Bursts and multi-beat transfers extend the collection. A burst transaction has N data beats across N cycles; reconstruction must collect all beats into the transaction's data array — not just the first.

The motivation, in one line: reconstruction is non-trivial because the transaction lives across time, not in one cycle — the monitor must follow the protocol's framing to collect each field at its valid cycle, assemble the full transaction across its whole duration, and emit only when complete, which is exactly the inverse of how the driver serialized it.

Mental Model

Hold reconstruction as the deserializer mirroring the serializer:

The driver serialized the transaction onto the wire over time; the monitor deserializes it back — collecting each field as it arrives, in the protocol's framing, and assembling the whole before emitting. Picture a package being shipped over a conveyor belt. The sender (the driver) took a complete package (the transaction) and disassembled it into parts that travel the belt one after another — the label (address) goes first, the contents (data) follow several positions later, and a big order ships as many boxes in sequence (a burst). That's serialization: one object spread across the belt over time. The receiver (the monitor) stands at the end of the belt and must reassemble the original package: it catches the label as it passes, waits for the contents to arrive at their position, catches those, gathers all the boxes of a multi-box order — and only when the last box has passed does it hand over the reassembled package (emit the transaction). Two things make the receiver correct. It must know the belt's framingwhich position each part rides on — so it catches each part at the right moment (catch the contents too early and you grab the previous order's contents). And it must wait for completeness — hand over the package only when whole, never a half-assembled box. The receiver is the mirror of the sender: the sender took apart and spread across the belt; the receiver catches across the belt and puts back together.

So reconstruction is deserialization mirroring serialization: the driver disassembled the transaction across time, the monitor reassembles it across timecatching each field at its framed position, gathering the whole, and emitting only when complete. The monitor needs the same protocol framing the driver used, run backwards: where the driver asked "what do I drive this cycle?", the monitor asks "what do I collect this cycle?" — and assembles the answer into a transaction.

Visual Explanation — reconstruction is the inverse of driving

The defining picture is the mirror: the driver serializes a transaction into timed pins; the monitor deserializes timed pins back into a transaction.

The driver serializes a transaction into timed pins; the monitor deserializes timed pins into a transactionone transactionserialize: unpack across cyclesserialize:unpack across…deserialize: collect across cyclesdeserialize:collect across…reassembledtransactionTransaction (in)driver's inputDriver — serializetxn → timed pins (12.2)Timed pin sequenceaddr phase, data phase, beatsMonitor — deserializetimed pins → txnTransaction (out)reconstructed12
Figure 1 — reconstruction is the inverse of the driver's serialization. The driver takes one transaction and unpacks it into a timed sequence of pin values across cycles (address phase, data phase, burst beats) — serialization (Module 12.2). The monitor does the inverse: it observes that timed pin sequence and re-packs it into a transaction — collecting each field at the cycle it appears and assembling the whole — deserialization. The two are mirror images: the driver spreads a transaction across time; the monitor gathers it back across time. Both need the same protocol framing, run in opposite directions.

The figure shows reconstruction as serialization run backwards. On the driver side (Module 12.2), one transaction goes in, the driver serializes it — unpacking the single object into a timed pin sequence: the address driven at the address phase, the data at the data phase, the beats of a burst across successive cycles. The transaction has been spread across time on the bus. On the monitor side, the monitor does the inverse: it observes that same timed pin sequence and deserializes it — collecting each field at the cycle it appears and re-packing them into a reconstructed transaction. The crucial reading is the mirror symmetry: the driver and monitor are the same protocol framing run in opposite directions. The driver, knowing the framing, asks "what do I drive this cycle?" and spreads the transaction out; the monitor, knowing the same framing, asks "what do I collect this cycle?" and gathers it back. The warning-colored node in the middle — the timed pin sequence — is the shared artifact: it's what the driver produces and the monitor consumes, the common ground where the transaction exists as spread-out pin activity rather than as a single object. This is why reconstruction needs the protocol's framing: to reverse the serialization, the monitor must know the same thing the driver knewwhich field rides which cycle — just applied to collecting instead of driving. The diagram is the conceptual heart of the chapter: reconstruction is not a fresh problem; it's the driver's serialization inverted, and a monitor that gets the framing right reassembles exactly the transaction the driver disassembled.

RTL / Simulation Perspective — the reconstruction collection

In code, reconstruction is a collection across cycles: sample the address at the address phase, wait for the data phase, sample the data there, then build and emit. The code shows the multi-cycle gather.

reconstruction: collect each field at its phase, across the transaction's duration
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
task run_phase(uvm_phase phase);
  forever begin
    bus_item tr = bus_item::type_id::create("tr");
 
    // --- ADDRESS PHASE: collect the address when it is valid ---
    @(posedge vif.clk iff (vif.valid && vif.is_addr_phase));
    tr.addr    = vif.addr;          // collect addr AT the address phase
    tr.is_read = vif.wr ? 0 : 1;
 
    // --- DATA PHASE: WAIT for it, then collect the data when IT is valid ---
    @(posedge vif.clk iff (vif.valid && vif.is_data_phase));
    tr.data    = vif.data;          // collect data AT the data phase (NOT the addr cycle)
 
    // --- BURST: collect all beats into the transaction's data array ---
    for (int i = 0; i < tr.len; i++) begin
      @(posedge vif.clk iff vif.beat_valid);
      tr.beats.push_back(vif.data); // gather every beat across its cycle
    end
 
    ap.write(tr);                   // EMIT only now — transaction is COMPLETE (13.4)
  end
  // ✗ sampling tr.data at the ADDRESS phase captures a stale/not-yet-valid value (DebugLab)
  // ✗ emitting before the data/burst is collected broadcasts an INCOMPLETE transaction
endtask

The code makes reconstruction's time structure explicit. The loop reconstructs one transaction per pass, and within a pass it moves through the transaction's phases in order. The address phase: @(posedge vif.clk iff (vif.valid && vif.is_addr_phase)) waits for the address phase, then tr.addr = vif.addr collects the address there — at the cycle it's valid. The data phase: a separate @(...) waits for the data phase (which may be cycles later), then tr.data = vif.data collects the data there — crucially, not at the address cycle, where data isn't valid yet. The burst: a loop gathers every beat (tr.beats.push_back(vif.data)) across its cycle, collecting all of a multi-beat transfer. Only after all phases are collected does ap.write(tr) emit — the transaction is complete. The two negative comments mark the traps: sampling data at the address phase captures a stale/not-yet-valid value (the DebugLab), and emitting before collection broadcasts an incomplete transaction. The shape to carry: reconstruction code walks the protocol's phases in timeone synchronization per phase, collecting each field where it's valid — and emits once, whole. It's structurally the mirror of the driver's serialization loop (Module 12.2), which drove each phase in turn; here the monitor collects each phase in turn.

Verification Perspective — completeness and correctness

A reconstructed transaction is only useful if it's complete (all fields the scoreboard needs) and correct (each field sampled at its valid cycle). Both follow from framing-aware collection.

Each field is collected at its valid phase and assembled into a complete transaction emitted only when wholecollected @ addrphasecollected @ dataphaseall beatscollectedcomplete + correct → emit oncecomplete +correct → emit…Address fieldvalid @ addr phaseData fieldvalid @ data phaseBurst beatsvalid across beatsAssemble transactionevery field, each at its phaseComplete transactionemitted when whole (13.4)12
Figure 2 — correct reconstruction collects every field at its valid cycle, then emits a complete transaction. Each field has a phase where it's valid on the bus: the address at the address phase, the data at the data phase, the beats across the burst. The monitor collects each at its phase (correctness — never sampling a field before it's valid) and assembles all of them (completeness — every field the scoreboard needs) into one transaction, emitted only when whole. A field sampled at the wrong phase is wrong; a field omitted makes the transaction incomplete. Both break the scoreboard's check.

The figure shows the two quality properties reconstruction must hold. Correctness — each field is collected at its valid phase: the address at the address phase, the data at the data phase, the burst beats across the beats (the warning-colored nodes mark where each field is valid — its phase). The monitor must sample each field at its phase, never before — a field sampled at the wrong phase captures a stale or not-yet-valid value, producing a wrong field. Completenessall the fields are gathered into the assembled transaction: every field the scoreboard and coverage need, none omitted. Only when the transaction is both complete and correct does the monitor emit it (once, when whole). The verification stakes are direct: the scoreboard checks the reconstructed transaction against expected, so a wrong field (correctness failure) produces a false mismatch (the scoreboard flags a bug that isn't there — the pins were right, the reconstruction was wrong), and an incomplete transaction (completeness failure — a missing field left at its default) also produces a false mismatch or a missed check. Either way, reconstruction errors masquerade as DUT bugs — the most confusing kind of failure, because the DUT is innocent and the testbench is lying. This is why reconstruction must be framing-exact: the scoreboard trusts the reconstructed transaction as ground truth (Module 13.1), so the reconstruction must actually be ground truth — every field, correct, at its phase, complete. Get the framing right and the reconstruction is what happened; get it wrong and the testbench invents a discrepancy the silicon never had.

Runtime / Execution Flow — collect across phases, then emit

At run time, reconstruction walks the transaction's phases in order — synchronizing to each, collecting its field — and emits only after the last. The flow shows the phase walk.

Reconstruction walks phases: collect address, collect data, collect beats, then emit the complete transactionwait addr phase → collect addr · wait data phase → collect data · collect beats · emit when completewait addr phase → collect addr · wait data phase → collect data · collect beats · emit when complete1Wait address phase, collect addresssynchronize to the address phase; sample the address where it'svalid.2Wait data phase, collect datasynchronize to the data phase (possibly later); sample the datathere — not at the address cycle.3Collect all burst beatsgather every beat across its cycle into the transaction's dataarray.4Emit when completethe transaction is whole — broadcast it once via the analysis port(13.4).
Figure 3 — reconstruction walks the transaction's phases across time. It waits for the address phase and collects the address. It waits for the data phase (possibly cycles later) and collects the data. For a burst, it collects every beat across its cycle. Only when the last field is collected — the transaction is complete — does it emit. Each step synchronizes to a phase and collects a field; the emit happens once, when whole. This is the driver's serialization loop run in reverse: collect each phase instead of drive each phase.

The flow is reconstruction as a walk through time. Collect the address (step 1): synchronize to the address phase and sample the address where it's valid — the first field of the transaction's life. Collect the data (step 2): synchronize to the data phase — which may be several cycles later — and sample the data there, not at the address cycle (where data isn't valid yet). Collect the beats (step 3): for a burst, gather every beat across its cycle into the transaction's data array — the transaction isn't done until all beats are in. Emit when complete (step 4): only now, with every field collected, broadcast the transaction once (Module 13.4). The runtime insight is that reconstruction takes as long as the transaction takes — it's not an instant; it spans the transaction's whole duration, synchronizing to each phase in turn. This is precisely the driver's serialization loop (Module 12.2) run in reverse: where the driver waited for each phase and drove the field, the monitor waits for each phase and collects the field. The symmetry is exact — same phases, same framing, same number of synchronizations — just collect where the driver drove. And the emit-when-complete discipline mirrors the driver's done-when-the-last-phase-is-driven: the monitor emits exactly when the transaction is whole, the same moment the driver would consider the transaction finished. The flow is reconstruction living through the transaction's lifetime, phase by phase, gathering as it goes, and handing over the assembled transaction at the end.

Waveform Perspective — collecting fields across cycles

Reconstruction's multi-cycle nature is visible on a timeline: the address appears at one cycle, the data at a later cycle, and the monitor collects each at its phase, emitting the assembled transaction only at the end. The waveform shows the gather.

The monitor collects the address and data at their separate phases, then emits the complete transaction

12 cycles
The monitor collects the address and data at their separate phases, then emits the complete transactionaddress phase: addr=40 valid; monitor collects the addressaddress phase: addr=40…data phase (cycles later): data=C3 valid; monitor collects the data HEREdata phase (cycles lat…both fields collected → emit the complete reconstructed transactionboth fields collected …clkaddr_phaseaddr--40--------------------data_phasedata--------C3--------------collect_addrcollect_datamon_emitt0t1t2t3t4t5t6t7t8t9t10t11
Figure 4 — reconstruction across cycles. The address is valid at the address phase (cycle 1); the monitor collects it (collect_addr). The data is valid at the data phase several cycles later (cycle 4); the monitor collects it THERE (collect_data) — not at the address cycle, where data is not yet valid. Only after both fields are collected does mon_emit pulse, broadcasting the complete reconstructed transaction. Sampling data at cycle 1 would capture the stale pre-data value — a wrong field from a correct bus.

The waveform shows reconstruction spread across cycles. At the address phase (cycle 1), addr_phase asserts and addr carries 40; the monitor collects the addresscollect_addr pulses there. Then, several cycles later, at the data phase (cycle 4), data_phase asserts and data carries C3; the monitor collects the datacollect_data pulses there, at the data phase, not at the address cycle. Only after both fields are collected does mon_emit pulse (cycle 5), broadcasting the complete reconstructed transaction (addr=40, data=C3). The crucial visual is the separation in time: the address and data are valid at different cycles, and the monitor's collect pulses line up with each field's phase — that alignment is correct reconstruction. The counterfactual is the bug: if the monitor sampled data at cycle 1 (the address cycle), data is still -- (not yet valid) — it would capture a stale/garbage value, producing a transaction with the wrong data field despite the bus being perfectly correct. Reading a waveform for reconstruction correctness — does each collect pulse line up with that field's valid phase? does emit happen only after the last field? — is how you verify the monitor is gathering the transaction correctly across its duration. The picture to carry: reconstruction is visible as collect-pulses marching across the transaction's phases, each aligned to where its field is valid, with the emit at the end — the transaction assembled across time, not snapped in one cycle.

DebugLab — the wrong transaction from a correct bus

A reconstructed transaction with the wrong data field, though the DUT drove the bus correctly

Symptom

A scoreboard reported a data mismatch: the expected transaction had data=C3, but the observed (reconstructed) transaction had data=00 (or a stale value). The failure pointed at the DUT — "the DUT drove the wrong data." But waveform inspection showed the bus was perfectly correct: at the data phase, data did carry C3, exactly as expected. The DUT was innocent. Yet the monitor reported the wrong data, so the scoreboard flagged a bug that didn't exist — a false mismatch originating inside the monitor.

Root cause

The monitor sampled all fields in one cycle — at the address phase — treating the transaction as single-cycle. So it collected the address correctly, but sampled data before the data phase, capturing the stale, not-yet-valid value instead of the real C3 that arrived cycles later:

why a correct bus produced a wrong transaction
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
✗ sampling ALL fields in one cycle (treating a multi-cycle transaction as single-cycle):
  @(posedge vif.clk iff vif.valid);   // the ADDRESS phase
  tr.addr = vif.addr;                 // ✓ addr is valid here → 40 (correct)
  tr.data = vif.data;                 // ✗ data is NOT valid yet → stale 00 (WRONG)
  ap.write(tr);                       // emits {addr=40, data=00} — wrong data, correct bus
 
✓ collect each field AT its phase (follow the protocol framing):
  @(posedge vif.clk iff (vif.valid && vif.is_addr_phase));
  tr.addr = vif.addr;                 // collect addr at the address phase
  @(posedge vif.clk iff (vif.valid && vif.is_data_phase));
  tr.data = vif.data;                 // collect data at the DATA phase → C3 (correct)
  ap.write(tr);                       // emits {addr=40, data=C3} — matches the bus

This is the framing bug — the most insidious reconstruction failure, because the DUT is correct and the monitor is wrong, so the symptom accuses the innocent party. The monitor treated a multi-cycle transaction as if it were single-cycle: it synchronized once (to the address phase) and sampled every field there. The address was valid at that cycle, so tr.addr came out right (40) — which masks the bug, making it look like reconstruction "mostly works." But data is not valid at the address phase — it arrives cycles later, at the data phase — so tr.data captured the stale pre-data value (00), producing a transaction {addr=40, data=00} that is wrong in the data field even though the bus carried C3 perfectly. The scoreboard, trusting the reconstructed transaction as ground truth, compared data=00 against expected data=C3 and flagged a mismatch — a false one, invented by the monitor. The fix is to follow the protocol's framing: synchronize to the address phase and collect the address, then synchronize separately to the data phase and collect the data there — gathering each field at the cycle it's valid, across the transaction's full duration. Now tr.data captures the real C3, the reconstructed transaction matches the bus, and the scoreboard's check is meaningful again. The general lesson, and the chapter's thesis: a transaction is multi-cycle, so the monitor must collect each field at the protocol cycle it appears — not sample everything in one cycle — because sampling a field before its phase captures a stale value, producing a wrong transaction from a correct bus that the scoreboard reports as a false DUT mismatch. Reconstruction must mirror the driver's framing: each field gathered where the driver drove it.

Diagnosis

The tell is a scoreboard mismatch where the bus is correct but the reconstructed transaction is wrong. Diagnose framing errors:

  1. Compare the reconstructed transaction against the waveform. If the bus carried the right value at the field's phase but the transaction has the wrong value, the monitor sampled at the wrong cycle.
  2. Check how many synchronizations the monitor does. One sync that collects all fields is the framing bug; the monitor needs one sync per phase.
  3. Look for a field sampled before its valid phase. A data field sampled at the address phase captures the stale value — match each sample against the protocol's phase for that field.
  4. Suspect the monitor before the DUT when only some fields are wrong. A field that's right (address) and one that's wrong (data) points at single-cycle sampling of a multi-cycle transaction.
Prevention

Reconstruct each field at the protocol cycle it appears:

  1. Synchronize once per phase. Wait for the address phase and collect the address; wait separately for the data phase and collect the data; collect each field where it's valid.
  2. Mirror the driver's framing. Reconstruction is serialization reversed — collect each field at the cycle the driver drove it; reuse the protocol's phase definitions.
  3. Qualify samples with valid. Sample a field only when its handshake/valid says it's meaningful, never on a phase where it's stale or X.
  4. Emit only when complete. Collect all fields (and all burst beats) before broadcasting; never emit a partially gathered transaction.

The one-sentence lesson: a transaction is multi-cycle, so reconstruct it by collecting each field at the protocol cycle it appears — one synchronization per phase, mirroring the driver's framing — and emit only when complete; sampling every field in one cycle captures fields before they're valid, producing a wrong transaction from a correct bus that the scoreboard reports as a false DUT mismatch.

Common Mistakes

  • Sampling all fields in one cycle. A multi-cycle transaction must be collected across phases; sampling everything at once captures fields before they're valid (stale/X).
  • Sampling a field before its phase. Each field is valid only at its phase; sample it earlier and you capture a stale value — a wrong field from a correct bus.
  • Emitting an incomplete transaction. Broadcasting before the last field (or burst beat) is collected sends a transaction with a default/garbage field — a false mismatch.
  • Not mirroring the driver's framing. Reconstruction is serialization reversed; ignoring the protocol's phase structure makes reconstruction guess instead of follow.
  • Dropping burst beats. A multi-beat transfer needs every beat collected; capturing only the first loses the rest of the data.
  • Blaming the DUT for a reconstruction error. A correct bus with a wrong reconstructed field is a monitor bug, not a DUT bug — check the framing before the design.

Senior Design Review Notes

Interview Insights

Transaction reconstruction is how the monitor turns pin-level activity back into a transaction object — the inverse of the driver's serialization. The driver took a single transaction and spread it across multiple cycles on the bus: the address at the address phase, the data at the data phase, the beats of a burst across successive cycles. The monitor must do the reverse — collect those fields back into one transaction. The reason it's more than reading the pins once is that a transaction is multi-cycle: the fields don't all exist on the bus at the same moment. The address is valid at the address phase, but the data may not arrive until several cycles later at the data phase, and a burst has many beats across many cycles. So the monitor can't just sample everything in one cycle; it has to follow the protocol's framing — know which cycle each field appears on, synchronize to that phase, and sample the field there. It collects the address at the address phase, waits for the data phase and collects the data there, gathers all the burst beats, and only emits the transaction once it's complete. If it sampled all the fields in one cycle, it would capture the address correctly but the data before it's valid, getting a stale value — a wrong transaction even though the bus was perfectly correct. So reconstruction is a framing-aware collection across the transaction's full duration, which is exactly the driver's serialization run backwards: where the driver asked what to drive each cycle, the monitor asks what to collect each cycle, and assembles the result.

Because the driver and monitor are the same protocol framing applied in opposite directions. The driver serializes — it takes one transaction object and unpacks it into a timed sequence of pin values, driving each field at the cycle the protocol says it belongs: address at the address phase, data at the data phase, beats across the burst. That spreads the single transaction across time on the bus. The monitor deserializes — it observes that same timed pin sequence and re-packs it into a transaction, collecting each field at the cycle it appears and assembling the whole. So they're mirror images: the driver disassembles a transaction across time, the monitor reassembles it across time. The important consequence is that the monitor needs the same protocol knowledge the driver has, just run backwards. The driver, to serialize, must know what to drive each cycle; the monitor, to deserialize, must know what to collect each cycle — and it's the same framing, the same phase structure, the same number of synchronizations. Concretely, the driver's run loop waits for each phase and drives the field; the monitor's run loop waits for each phase and collects the field. That symmetry is useful in practice: if you understand how the driver serialized a protocol, you know exactly how the monitor must reconstruct it — collect each field where the driver drove it. And it explains why reconstruction is protocol-specific: it can't be generic, because the framing — which field rides which cycle — is defined by the protocol, and the monitor has to follow it to reverse the serialization correctly.

Exercises

  1. Trace the inverse. Given a driver that serializes a transaction as address-then-data, describe the monitor's reconstruction loop step by step.
  2. Spot the framing bug. A monitor samples address and data in the same cycle. Explain what the data field will contain and why the scoreboard mismatches.
  3. Reconstruct a burst. Sketch the collection loop for a 4-beat burst transaction, including where the emit goes.
  4. Diagnose the innocent DUT. The scoreboard flags a data mismatch but the waveform shows the correct data at the data phase. Name the bug and the fix.

Summary

  • Transaction reconstruction is the monitor deserializing pin-level activity back into a transaction — the inverse of the driver's serialization (Module 12.2): where the driver spread a transaction across cycles, the monitor gathers it back.
  • A transaction is multi-cycle — fields don't all exist on the bus at once — so the monitor must collect each field at the protocol cycle it appears: the address at the address phase, the data at the data phase (often later), every burst beat across its cycle.
  • Reconstruction needs the same protocol framing the driver used, run backwards: one synchronization per phase, collecting where the driver drove, and emitting only when the transaction is complete.
  • A reconstructed transaction must be correct (each field sampled at its valid phase) and complete (all fields gathered) — a field sampled at the wrong phase captures a stale value, producing a wrong transaction from a correct bus that the scoreboard reports as a false DUT mismatch.
  • The durable rule of thumb: reconstruct a transaction by collecting each field at the protocol cycle it appears — one synchronization per phase, mirroring the driver's framing — and emit only when complete; never sample every field in one cycle, because a field grabbed before its phase is stale, making the monitor invent a discrepancy the silicon never had.

Next — Protocol Monitoring: reconstruction assembles what happened into a transaction; protocol monitoring asks whether what happened was legal — the monitor as a protocol checker, watching the interface for handshake, ordering, and timing violations the DUT must never commit, and flagging them at the moment they occur.