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

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • Reading Paths
  • Concept Map
  • How to Read the Diagrams
  • Part 0: What Is a Protocol?10
  • Part 1: Timing and Clocking11
  • Part 2: Encoding and Framing12
  • Part 3: Handshakes13
  • Part 4: Flow Control17
  • Part 5: Transactions19
    • Reads and Writes Are Not Symmetric
    • The Request/Response Model
    • Address Maps and Decoding
    • Register Semantics
    • Combined and Split Transactions
    • Independent Channels
    • Posted and Non-Posted Writes
    • Bursts
    • Alignment, Strobes and Narrow Transfers
    • Boundary Rules
    • Width and Endianness Conversion
    • Transaction Attributes
    • Atomics
    • Sideband or In-Band
    • Interrupts and Notification
    • Descriptors, Rings and Doorbells
    • Bridges and Protocol Conversion
    • Protocols Compared: Transactions
    • Drills: Transactions
  • Part 6: Concurrency and Performance17
  • Part 7: Ordering13
  • Part 8: Sharing and Arbitration12
  • Part 9: Deadlock and Liveness13
  • Part 10: Reliability and Recovery20
  • Part 11: Bring-Up and Link Management10
  • Part 12: Power8
  • Part 13: Shared State and Coherence9
  • Part 14: Security and Isolation7
  • Part 15: Specifying and Verifying11
  • Part 16: Protocols Dissected17
  • Part 17: Capstones5
  • Part 18: Interview Preparation6
Loading lesson

‹Part 5: Transactions
  1. Topics
  2. First Principles of Hardware Protocols
  3. Part 5: Transactions
  4. Boundary Rules

Part 5 · Transactions · Senior (S)

Boundary Rules

Why protocols forbid bursts from crossing a page boundary such as 4 KB: decoders and address translation work per page. How to detect a crossing burst and split it.

On this page

    Note

    Level: Senior (S) · Answers: What exactly is being asked?

    Before this: Bursts, Address Maps and Decoding

    A DMA engine issues a 256-byte burst starting at 0x0FC0. The first 64 bytes belong to a buffer in one 4 KB page; the remaining 192 bytes run into the next page, which the operating system gave to a different program, and which the address-translation unit maps to a completely different physical location. The engine's burst describes one contiguous range. Physically, it is two.

    Why do protocols forbid bursts from crossing certain boundaries, and what should a requester do with a transfer that would?

    The obvious answer, and why it breaks

    A burst gives one start address and lets the target compute the rest (lesson 5.8), so the obvious rule is that any burst, of any length, from any address, is fine. But every agent that looks at the address only once, at the start of the burst, assumes the whole burst lives where the start lives. The decoder sends the whole burst to the target that owns the start address; an address-translation unit translates the start address and adds offsets. Both are wrong the moment the burst crosses into a region with a different owner or a different translation.

    The idea: no burst crosses a page

    Pick a boundary size that every agent can rely on: targets are placed on multiples of it, and address translation works in pages at least that large. Forbid any burst from crossing it. Then the start address alone decides where the whole burst goes, and every agent can decode and translate once per burst. 4 KB is the common choice because it is the smallest common memory-management page.

    A crossing burst would be decoded and translated as if it lived entirely in the first page; split, each piece stays in one page.

    Build it: detect and split

    A burst of n beats of size bytes covers [start, start + n·size). It crosses if its first and last bytes are in different pages. The splitter issues one burst per page.

    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
    28
    29
    30
    """Find INCR bursts that would cross a 4 KB boundary, and split them.
    
    A burst of n beats of `size` bytes from `start` covers [start, start + n*size).
    It crosses a boundary if its first and last bytes lie in different 4 KB pages.
    A splitter issues one burst per page instead.
    """
    PAGE = 4096
    
    
    def crosses(start, n, size):
        return start // PAGE != (start + n * size - 1) // PAGE
    
    
    def split(start, n, size):
        pieces, a, left = [], start, n
        while left:
            room = (PAGE - a % PAGE) // size          # whole beats left in this page
            take = min(left, room)
            pieces.append((a, take))
            a, left = a + take * size, left - take
        return pieces
    
    
    for start, n, size in ((0x0F00, 16, 16), (0x0FC0, 16, 16), (0x1FF8, 4, 8)):
        parts = split(start, n, size)
        desc = " + ".join(f"{k} beat{'s' if k > 1 else ''} at 0x{a:04X}" for a, k in parts)
        print(f"INCR{n} x {size} B at 0x{start:04X}: {'crosses' if crosses(start, n, size) else 'fits'} -> {desc}")
        assert sum(k for _, k in parts) == n
        assert all(not crosses(a, k, size) for a, k in parts)
    print("PASS: every piece stays inside one 4 KB page and the pieces cover the original burst")

    It prints:

    Diagram
    INCR16 x 16 B at 0x0F00: fits -> 16 beats at 0x0F00
    INCR16 x 16 B at 0x0FC0: crosses -> 4 beats at 0x0FC0 + 12 beats at 0x1000
    INCR4 x 8 B at 0x1FF8: crosses -> 1 beat at 0x1FF8 + 3 beats at 0x2000
    PASS: every piece stays inside one 4 KB page and the pieces cover the original burst

    The first burst ends exactly at 0x0FFF, so it fits. The second is the opening's DMA burst: 4 beats fit before 0x1000, the other 12 start a new burst there. The third shows that even a short burst crosses if it starts near the end of a page.

    What the rule protects

    Agent

    Works per

    What a crossing burst would break

    Address decoder

    Target region (placed on 4 KB multiples)

    The tail of the burst goes to the wrong target

    Address translation (IOMMU or MMU)

    Page (4 KB or larger)

    The tail is translated with the wrong page's mapping: data lands in another program's memory

    Protection checks

    Page or region

    The tail escapes the permission check made for the start

    Targets with internal pages (some memories)

    Row or page

    Extra work, or wrong behaviour, if a burst spans two internal pages

    Requesters pay: a DMA engine must split transfers at boundaries. Because a 4 KB page holds many bursts, the cost is small: at most one extra burst per page crossed.

    How real protocols chose

    Protocol

    Boundary rule

    AXI

    No burst may cross a 4 KB address boundary. A 256-beat INCR burst therefore fits only if its size and start address keep it inside one 4 KB page.

    DCLink (step 4)

    A burst that would run past the end of memory (0x00FFF) is refused with an error completion.

    What breaks

    A DMA engine (illustrative) split transfers at 4 KB boundaries correctly for writes but not for reads, because the read path had been written later by a different engineer. On systems with an IOMMU, a read that crossed a page fetched its tail from the wrong physical page, and the bug appeared only when buffers happened to straddle pages, which depended on memory fragmentation. A boundary-checker assertion on the bus would have caught it the first time it happened.

    Why this matters

    Senior lens. Boundary rules let every agent decode, translate and check once per burst; they are cheap insurance against corrupting someone else's memory. Put a boundary assertion on every requester port, make every DMA engine split at boundaries on both read and write paths, and test with buffers that start a few bytes before a page boundary.

    Interview

    Asked: "Why can't an AXI burst cross 4 KB?"

    Weak answer: Because the spec says so.

    Strong answer: Because decoders and address translation look at the burst's start address only once. If a burst crossed 4 KB, its tail could belong to a different target, or to a different virtual page that the IOMMU maps somewhere else entirely, and it would be decoded, translated and permission-checked as if it lived in the first page. 4 KB is the smallest common page, so forbidding crossings lets every agent work once per burst. Requesters split transfers at boundaries, costing at most one extra burst per page.

    Follow-ups: (1) How do you split a burst that would cross? (2) Why 4 KB and not 64 KB?

    Check yourself Does an INCR burst of 8 beats × 16 bytes starting at 0x1F90 cross a 4 KB boundary?

    It covers 0x1F90 to 0x200F, so yes: split into 7 beats from 0x1F90 and 1 beat from 0x2000.

    Check yourself Why is an IOMMU the most dangerous place for a crossing burst?

    It translates the start address's page; the tail would be written to the physical memory behind the wrong page, possibly another program's, with no error.

    Key takeaways

    • Protocols forbid bursts from crossing page boundaries so every agent can decode, translate and check once per burst.

    • 4 KB is the common boundary because it is the smallest common page.

    • Requesters split transfers at boundaries: at most one extra burst per page crossed.

    Keep going

    Next: Lesson 5.11, Width and Endianness Conversion. Joining buses of different widths and byte orders, and what gets lost or gets expensive.

    Related topics

    • Part 5 overview: Transactions

    Previous

    77 / 234

    Next: Width and Endianness Conversion

    Up next

    Up nextWidth and Endianness Conversion

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Reads and Writes Are Not Symmetric
    • The Request/Response Model
    • Address Maps and Decoding