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
    • Topologies and Bridges
    • AXI Integration Details
    • Ordering and Deadlock at the Top
    • QoS and Arbitration
    • NoC Basics
    • Coherent Interconnect View
      • What Changes with Coherent Masters
      • I/O Coherence Options for DMA
      • Migration Path from NanoSoC
    • Firewalls and Protection
    • Bandwidth and Latency Verification
  • Clock and Reset Architecture24
  • Power Architecture21
  • Interrupts, DMA and Peripherals15
  • Memories, Boot and Security21
  • IP Integration and Handoff21
  • Top-Level Verification and Bring-up21
  • Package, Pads and I/O18
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←Coherent Interconnect View
  1. Topics
  2. SoC Design
  3. Interconnect and Bus Fabrics
  4. Coherent Interconnect View
  5. I/O Coherence Options for DMA
On this page

    Part 4 of 14, lesson 19 of 26Part 4 of 14/Interconnect and Bus Fabrics/Lesson 19 of 26All levels

    I/O Coherence Options for DMA

    Software maintenance against a coherent port: the DMA coherence choice, costed on the 64-word NanoSoC job. Illustrative numbers.

    Why it matters

    The NanoSoC job moves buffers the CPU also touches, and today software keeps them consistent by placement: the SBR writes its output to SRAM1, which is non-cacheable, so no stale copy can exist. The price is speed: reading back 64 words from SRAM1 takes 64 x 93.75 ns = 6,000 ns, as in the boot self-test. A cacheable buffer would read the same 256 bytes as 16 line fills of 125 ns, 2,000 ns, three times faster. The day a buffer must be cacheable for that speed, or for sharing, the placement trick stops working and the integrator chooses between teaching software to maintain the caches or teaching the fabric to snoop the SBR's accesses. NanoSoC has no data cache; the numbers below describe a hypothetical one.

    The core idea

    Software maintenance means cleaning cached writes before the SBR reads a buffer and invalidating cached copies before the CPU reads what the SBR wrote, with barriers so the maintenance itself is ordered. It costs code, discipline and cycles, and one missed invalidate corrupts silently. An I/O-coherent port, the ACE-Lite style, lets the SBR's reads snoop the caches instead: the hardware finds the newest copy wherever it lives. Its writes matter too: an I/O-coherent write must invalidate or update the other copies of the line, or the other cache keeps serving the old value. The price is snoop traffic per burst: each 16-beat SBR burst is 64 bytes, 4 lines, 4 snoops, and a 64-word job in each direction is 16 lines, so 32 snoops per job.

    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
    # Illustrative: costing one 64-word job on a hypothetical cacheable buffer (NanoSoC has no data cache).
    T_CPU = 1e9 / 192e6
    LINES = 256 // 16 # 16 lines of 16 bytes
    MAINT_CYCLES = 2 # illustrative clk_cpu cycles per line operation
    uncached_readback = 64 * 93.75 # ns, single reads of SRAM1 as in the boot self-test
    cached_readback = LINES * 125.0 # ns, 16 four-beat line fills
    assert uncached_readback == 6000.0 and cached_readback == 2000.0
    maint = 2 * LINES * MAINT_CYCLES * T_CPU # clean the source + invalidate the destination
    assert abs(maint - 333.3) < 0.1
    job = (64 + 8) * 1e9 / 96e6 # the DMA job itself, 750 ns
    assert abs(job - 750.0) < 0.1
    assert maint < 0.5 * job # maintenance is a modest tax on the job, if every line is covered
    snoops_per_job = LINES + LINES # 16 read-side + 16 write-side invalidations
    assert snoops_per_job == 32
    assert 16 * 4 // 16 == 4 # a 16-beat burst of 4-byte beats is 4 lines
    
    # why maintenance must be complete: a model of one cached line and memory
    def dma_reads(cpu_value, cleaned):
        memory = 0 # stale value in memory
        cache = cpu_value # CPU's dirty line
        if cleaned:
            memory = cache # clean writes the line back
        return memory
    
    assert dma_reads(0xAB, cleaned=True) == 0xAB
    assert dma_reads(0xAB, cleaned=False) != 0xAB # a missed clean makes the DMA read stale data
    print("PASS: 6000 ns uncached vs 2000 ns cached read-back, maintenance 333 ns per 750 ns job, 32 snoops per job, a missed clean is caught")

    What the review looks for

    • Every DMA buffer class states its coherence method: placement, maintenance, or coherent port.

    • Maintenance sequences name their barriers, and the driver review checks each path, including error exits.

    • A coherent port choice carries its snoop bandwidth row in the fabric budget, with write-side invalidations counted.

    Verify and debug

    Test both directions of staleness: CPU writes then the SBR reads, and the SBR writes then the CPU reads, with the caches hot in each case. A maintenance bug fails only when the line happens to be cached, so randomise cache state before each job. Watch for the error-exit trap: a job that ends early must still maintain the lines it touched, or the next job inherits stale data.

    Address-space visibility mistaken for coherence: the SBR reaches a buffer but sees stale data, and the team debugs reachability while the caches hold the answer. Reachability asks which addresses the master can see; coherence asks which copy is newest. Check the map for the first and the buffer attributes for the second.

    If asked how a DMA stays coherent, give both options with costs before recommending: maintenance is code and barriers per job (333 ns on a 750 ns job in this illustration), a coherent port is 32 snoops per job and a snoop-aware fabric. Then ask about the buffer pattern, because the pattern picks the answer.

    Check yourself DMA buffers move from SRAM1 to a cacheable shared region. What changes in the driver?

    Every job gains maintenance: clean before the SBR reads, invalidate before the CPU reads the output, barriers around both, including on error exits. Alternatively the SBR port goes coherent and the budget gains a snoop row, with the SBR's writes invalidating other copies.

    Related topics

    • What Changes with Coherent Masters

    • Next: Migration Path from NanoSoC

    • Cache Coherency: Coherent Versus Non-Coherent DMA

    Previous

    83 / 289

    Next: Migration Path from NanoSoC

    Up next

    Up nextMigration Path from NanoSoC

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error