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

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • The NanoSoC Tour
  • Reading Path
  • SoC Glossary10
  • SoC Metrics Reference
  • SoC Cheatsheet
  • What SoC Integration Is12
  • Architecture and Budgets21
  • Memory Maps and Address Decode26
  • Interconnect and Bus Fabrics26
  • Clock and Reset Architecture24
  • Power Architecture21
  • Interrupts, DMA and Peripherals15
  • Memories, Boot and Security21
  • IP Integration and Handoff21
    • IP Collateral and Versioning
    • Wrappers and Adapters
    • Integration Lint and Connectivity Checks
    • Top-Level SDC and Constraint Merge
    • DFT Integration
    • Debug Infrastructure
      • Debug Access and TAP Chaining
      • Trace and Cross-Triggers
      • Secured Debug and Debug Power
    • Safety and Fault Architecture
  • Top-Level Verification and Bring-up21
  • Package, Pads and I/O18
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←Debug Infrastructure
  1. Topics
  2. SoC Design
  3. IP Integration and Handoff
  4. Debug Infrastructure
  5. Trace and Cross-Triggers
On this page

    Part 9 of 14, lesson 17 of 21Part 9 of 14/IP Integration and Handoff/Lesson 17 of 21All levels

    Trace and Cross-Triggers

    Getting history out: trace sources, the funnel, bandwidth budgeting with overhead, and triggers across clock domains.

    Extension topic: NanoSoC v1 has no debug hardware. This lesson uses the NanoSoC debug extension described in the Debug Infrastructure overview; numbers marked illustrative belong to that extension only.

    Why it matters

    A halted CPU shows the state; trace shows the story: the last thousand branches before the hang, the DMA completion that never came, the interrupt that arrived one cycle too late. But trace is a firehose aimed at a straw, several sources producing words every clock into a funnel with one narrow exit. Without a bandwidth budget the trace overflows exactly on the interesting burst and records everything except the bug. The questions are how wide the exit must be, what it costs in pins, and what happens when it still overflows.

    The core idea

    Each trace source, the CPU instruction stream, the fabric transaction monitor, the DMA event flags, emits packets only on interesting events rather than every cycle: branches taken, error responses, job completions. A funnel merges the enabled sources with source tags and timestamps into one stream, so every packet carries overhead beyond its payload, and the stream leaves through a trace port or into a small on-chip buffer. The budget below is the standing calculation: filtered source rates plus packet overhead against exit bandwidth, with the overflow policy stated up front, stall the sources or drop with a marker, because silent wrap is how a trace lies. A filter that makes the stream exactly equal to the exit has no headroom, so the budget must show margin.

    The pin count belongs in the budget too. NanoSoC's user pins are 16 GPIO pads (the UART and SPI share six of them) and it has no debug or test pins, so a parallel trace port is a real cost: a 4-byte port is 32 data pins and a clock, and even a 2-byte port needs 16 data pins and a clock. Cross-triggers connect the domains: the DMA error flag halts the CPU trace, the CPU breakpoint starts fabric capture, each through a two-flop synchroniser with the level held, because a one-cycle pulse across the 96 to 24 MHz boundary is the lost-interrupt failure wearing a debug badge.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    # Trace bandwidth budget for the debug extension (all widths and filters illustrative).
    CPU_MHZ, FAB_MHZ, PKT_BYTES = 192.0, 96.0, 4          # NanoSoC clocks, 4-byte packets
    cpu_peak = CPU_MHZ * PKT_BYTES                          # every CPU cycle traced
    fab_peak = FAB_MHZ * PKT_BYTES                          # every fabric beat traced
    assert abs(cpu_peak - 768.0) < 0.1 and abs(fab_peak - 384.0) < 0.1
    
    cpu_real = cpu_peak / 16                                # 1-in-16 branch filter
    fab_real = 0.05 * fab_peak                              # fabric flags: 5 percent of beats
    OVERHEAD = 0.25                                         # source tag and timestamp
    payload = cpu_real + fab_real
    total = payload * (1 + OVERHEAD)
    assert abs(cpu_real - 48.0) < 0.01 and abs(fab_real - 19.2) < 0.01
    assert abs(total - 84.0) < 0.01, total
    
    def exit_bw(width_bytes, mhz):                          # single data rate port
        return width_bytes * mhz
    
    wide, narrow = exit_bw(4, 24.0), exit_bw(2, 24.0)       # 32 data pins vs 16 data pins
    assert wide == 96.0 and narrow == 48.0
    assert total < wide and (wide - total) / wide > 0.1     # fits with 12.5 percent headroom
    assert total > narrow, "the 2-byte port overflows: a policy is required"
    
    # size the on-chip buffer that rides out a 100 microsecond burst on the narrow port
    burst_s = 100e-6
    buffer_bytes = (total - narrow) * 1e6 * burst_s
    assert abs(buffer_bytes - 3600.0) < 1.0, buffer_bytes
    print("PASS: 84 MB/s total; 96 MB/s port fits with 12.5 percent headroom; 48 MB/s port overflows, 3600 B rides out 100 us")

    What the review looks for

    • The budget above recomputed for the shipped source set, with the filter assumptions and the packet overhead written beside each rate, and headroom stated.

    • The pin count of the trace port written next to its bandwidth, reconciled with the pins the chip can spare.

    • The overflow policy stated per source: stall or drop-with-marker, never silent wrap.

    • Every cross-trigger named with its synchroniser and its hold requirement, reviewed like any other crossing.

    Verify and debug

    Overflow the trace deliberately in simulation with all sources enabled and unfiltered: confirm the policy engages, stall back-pressures or markers appear, and no packet is silently lost. Test each cross-trigger across its ratio with alignment sweeps; a trigger that arrives but one cycle too late to stop the trace before the event is a trigger that decorates the failure without capturing it.

    Lost event across a clock domain: a one-cycle pulse from a fast domain never seen in a slow one. In debug clothing this is the trigger that fires but captures nothing, because the 96 MHz flag was a single cycle against the 24 MHz trace control. Caught by CDC lint and ratio-sweep tests; fixed with level-hold plus handshake or a sticky status bit the slow side clears.

    If asked to size a trace port, answer peak versus filtered: quote the unfiltered peak that proves a policy is needed, then the filtered rate plus packet overhead with the filter assumption stated, and the pin cost of the port. Then say the policy choice: stall for completeness when the system tolerates back-pressure, drop-with-marker when it does not.

    Check yourself The trace shows normal traffic then stops one packet before the error response. What failed?

    Either the stop trigger arrived late, so the error packet was never captured, or the funnel dropped packets during the burst without a marker. Check trigger latency first, then the overflow policy. A wrapping buffer would have kept the newest packets, so a wrap alone does not explain a missing error response.

    Related topics

    • Debug Access and TAP Chaining

    • Next: Secured Debug and Debug Power

    • Hardware Debug: Emulation and FPGA Prototyping

    Previous

    188 / 289

    Next: Secured Debug and Debug Power

    Up next

    Up nextSecured Debug and Debug Power

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error