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
      • Shared Bus, Crossbar and Hierarchy
      • Inside the AXI to APB Bridge
      • Bridge Costs and Where Bridges Belong
      • Register Slices and Timing Closure
    • AXI Integration Details
    • Ordering and Deadlock at the Top
    • QoS and Arbitration
    • NoC Basics
    • Coherent Interconnect View
    • 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

←Topologies and Bridges
  1. Topics
  2. SoC Design
  3. Interconnect and Bus Fabrics
  4. Topologies and Bridges
  5. Shared Bus, Crossbar and Hierarchy
On this page

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

    Shared Bus, Crossbar and Hierarchy

    One transaction at a time versus parallel paths: the NanoSoC 2 by 4 crossbar and its APB tree, with numbers.

    Why it matters

    The first symptom that points at the topology is a stream that runs at half speed for no visible reason. On NanoSoC the SBR-to-SRAM stream sustains 361.4 MB/s when source and destination sit in different banks, and 180.7 MB/s when they share one. Nothing is broken in the slow case: two masters are simply asking one single-port memory for data at once, and the fabric serialises them. Whether that serialisation happens everywhere or only at shared slaves is the difference between a shared bus and a crossbar, and it is decided before any RTL is written.

    The core idea

    A shared bus lets one transaction through at a time: every master arbitrates for the same wires, so the aggregate peak is the bus peak no matter how many masters are idle. A crossbar gives each slave its own arbiter and multiplexer, so masters talking to different slaves proceed in parallel and only collide when they want the same slave in the same cycle. The price is wiring and area that grow with masters times slaves, plus one arbiter per slave that must close timing every cycle.

    NanoSoC is a 2-master by 4-slave AXI4 crossbar: M0 is the CPU through its clock-domain bridge, M1 is the SBR, and the slaves are ROM, SRAM0, SRAM1 and the APB bridge. Behind that bridge sits a second level, an APB tree with a 12-bit address, one 96 MHz segment for the DMA and SBR registers and one 24 MHz segment behind the apb_cdc for the five slow peripherals. Hierarchy is the third idea: fast masters share a wide fast fabric, slow registers share a narrow slow bus, and a bridge with its own clock and power rules joins them. Memory traffic from the CPU and the SBR never queues behind a UART access, and the UART logic never pays for a 96 MHz clock tree. The one place accesses do queue is the bridge itself: S3 handles one access at a time, so a UART access in flight holds off any other access to the APB window, including an SBR register write, and the CPU itself waits 281.25 ns for each UART access because it has one access in flight.

    Where the bridges and crossings sit between the CPU, the crossbar and the peripherals.
    Where the bridges and crossings sit between the CPU, the crossbar and the peripherals.

    Worked example: what parallelism buys

    Peak on any 32-bit 96 MHz link is 4 bytes times 96 MHz, 384.0 MB/s. With 16-beat bursts and one arbitration bubble per burst the sustained rate is 384 times 16/17, 361.4 MB/s. The script below checks the NanoSoC table, then compares split traffic against shared-bank traffic: two banks give twice 361.4, one shared port gives half of 361.4 to each stream.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    W = 4 # bytes per beat on the 32-bit fabric
    F = 96.0 # MHz on clk_sys
    PEAK = W * F # 384.0 MB/s
    
    def sustained(burst):
        return PEAK * burst / (burst + 1)
    
    assert abs(PEAK - 384.0) < 1e-9
    assert abs(sustained(1) - 192.0) < 0.05
    assert abs(sustained(4) - 307.2) < 0.05
    assert abs(sustained(16) - 361.4) < 0.05
    split_total = 2 * sustained(16)
    shared_each = sustained(16) / 2
    assert abs(split_total - 722.8) < 0.1
    assert abs(shared_each - 180.7) < 0.05
    print("PASS: peak 384.0, burst-16 361.4, split 722.8 total, shared 180.7 each")

    What the review looks for

    • The topology paragraph names every master, every slave, and which pairs may proceed in parallel.

    • Each slave lists its worst-case concurrent demand, and the shared slaves show the sharing arithmetic above.

    • Slow peripherals sit behind a bridge, never on the fast fabric, with the latency budget that choice implies.

    Verify and debug

    Recheck the sharing arithmetic whenever a buffer moves: the 180.7 MB/s shared-bank trap fires exactly when the SBR's source and destination land in the same SRAM bank, because its read stream and its write stream then share one single-port memory. In simulation, run an SBR copy with source and destination in the same bank and confirm each direction sees about half the port rate; then move the destination to the other bank and confirm both recover to the full 361.4 MB/s. A CPU line-fill pattern competing with the SBR for one bank is a different case, the 69.8 and 279.3 MB/s split of the arbitration topic. For the bridge, issue a UART access and an SBR register write back to back and confirm the second waits for the first.

    A slow slave on a shared path: NanoSoC hangs five slow peripherals behind one bridge that serves one access at a time, so a 281.25 ns UART access holds S3 while an SBR register write waits behind it, and a peripheral that never answers would hold it for ever. The topology is right, but every shared hop needs its own worst-case wait written down, and the bridge needs a watchdog (256 clk_sys cycles, 2.67 us) so a dead slave costs one error instead of the whole APB window.

    If asked to choose a fabric for eight masters and twelve slaves, answer in three steps: add up worst-case demand against achievable DRAM-side efficiency, name the hotspot slave, then propose hierarchy with bridges by clock and power domain. Quote NanoSoC as the two-master version of the same argument.

    Check yourself Two masters stream into SRAM0 and SRAM1 respectively, then both into SRAM0. What rate does each stream see in each case?

    Split across banks each sees the full burst-16 rate, 361.4 MB/s. Sharing one single-port bank they split the port, about 180.7 MB/s each.

    Related topics

    • Next: Inside the AXI to APB Bridge

    • Protocol First Principles: AXI4

    • Protocol First Principles: APB

    • RTL: Bus Integration

    Previous

    59 / 289

    Next: Inside the AXI to APB Bridge

    Up next

    Up nextInside the AXI to APB Bridge

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Bridge Costs and Where Bridges Belong
    • Register Slices and Timing Closure