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
    • Partitioning and Hierarchy
      • Flat Versus Hierarchical
      • Boundary Choices and Feedthroughs
      • NanoSoC Partition Rationale
    • Area Budgets
    • Timing Budgets Across Hierarchy
    • Power Budgets
    • Bandwidth Budgets
    • Budget Governance
    • Multi-Die and Chiplet View
  • 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
  • Top-Level Verification and Bring-up21
  • Package, Pads and I/O18
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←Partitioning and Hierarchy
  1. Topics
  2. SoC Design
  3. Architecture and Budgets
  4. Partitioning and Hierarchy
  5. Boundary Choices and Feedthroughs
On this page

    Part 2 of 14, lesson 2 of 21Part 2 of 14/Architecture and Budgets/Lesson 2 of 21All levels

    Boundary Choices and Feedthroughs

    What may cross a partition boundary, what must never cross unregistered, and how to remove a feedthrough.

    Why it matters

    A signal that enters a partition only to leave it again is the quietest budget thief in the book. It is called a feedthrough: a test mode threaded through the fabric, the SBR interrupt (irq_sbr, controller input 2) routed via an unrelated wrapper, a clock enable daisy-chained through three blocks. Each one couples three things that should be independent — the source, the carrier and the sink — so a late change at either end re-opens the middle. Nothing crosses a NanoSoC boundary without a consumer, and feedthroughs are counted at review with the goal of zero.

    The core idea

    Four things may cross a boundary. Clocks and resets cross through dedicated trees into synchroniser or release cells, never as ordinary logic inputs. Power intent crosses as named control: isolation enables, switch controls and power-good returns. Protocol channels cross whole, with every signal of the interface in one place, never split across two boundaries. Configuration crosses as quasi-static values set before operation and never toggled during traffic. Everything else, and above all a signal that merely passes through, is refused a crossing until it is rerouted around the partition or given a genuine consumer inside.

    Crossing

    Allowed how

    NanoSoC example

    Clock and reset

    Clock through the clock tree; reset through a release cell per domain

    clk_sys and rst_sys_n into every system-side block

    Power control

    Named intent signals with an owner

    iso_sw_en into the APB bridge and SRAM0 wrapper

    Protocol channel

    Whole interface, one boundary, one owner

    Full APB bundle across the system-to-peripheral bridge

    Quasi-static config

    Set before traffic, synchronised once

    Clock-enable bits from the reset controller

    Feedthrough

    Not allowed in RTL; reroute or consume

    irq_sbr must not transit an unrelated wrapper

    Worked example: counting and removing one

    Suppose irq_sbr were wired through the SBR's neighbour wrapper on its way from the stream bridge to the interrupt controller: the wrapper would carry a port it never uses, and any change to interrupt routing would re-verify it. The bad version below does exactly that — the through port is marked so the checker can flag it — and the fixed version routes the signal around the wrapper, straight from the top level to the controller. A wrapper exposes only ports its core consumes; the audit after the modules proves the through port is gone and the signal count is conserved.

    nano_sbr_neighbour_bad.sv
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    // bad-example: irq_sbr transits a wrapper that never uses it (a feedthrough).
    module nano_sbr_neighbour_bad (
      input  logic        clk,
      input  logic        rst_n,
      input  logic [7:0]  paddr,
      input  logic        psel,
      input  logic        irq_sbr_in,
      output logic [31:0] prdata,
      output logic        irq_sbr_out
    );
      logic [31:0] core_reg;
      always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) core_reg <= 32'h0;
        else if (psel) core_reg <= core_reg + 1'b1;
      end
      assign prdata = (paddr[7:0] < 8'h14) ? core_reg : 32'h0;
      assign irq_sbr_out = irq_sbr_in;  // through port: no logic consumes it
    endmodule
    
    // Fixed: the wrapper exposes only ports its core consumes; irq_sbr stays outside.
    module nano_sbr_neighbour (
      input  logic        clk,
      input  logic        rst_n,
      input  logic [7:0]  paddr,
      input  logic        psel,
      output logic [31:0] prdata
    );
      logic [31:0] core_reg;
      always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) core_reg <= 32'h0;
        else if (psel) core_reg <= core_reg + 1'b1;
      end
      assign prdata = (paddr[7:0] < 8'h14) ? core_reg : 32'h0;
    endmodule
    
    module nanosoc_irq_top (
      input  logic        clk,
      input  logic        rst_n,
      input  logic        irq_sbr_src,
      output logic [31:0] sbr_rdata,
      output logic        irq_to_intc
    );
      // irq_sbr routes AROUND the wrapper, never through it.
      assign irq_to_intc = irq_sbr_src;
      nano_sbr_neighbour u_sbr (
        .clk(clk), .rst_n(rst_n), .paddr(8'h04), .psel(1'b1), .prdata(sbr_rdata)
      );
    endmodule
    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # Connectivity audit: a port is a feedthrough if its only fanout is an output.
    bad = {"clk": ["core"], "rst_n": ["core"], "paddr": ["core"],
           "psel": ["core"], "prdata": ["core"],
           "irq_sbr_in": ["irq_sbr_out"]}  # in -> out, never touches the core
    fixed = {"clk": ["core"], "rst_n": ["core"], "paddr": ["core"],
             "psel": ["core"], "prdata": ["core"]}  # irq_sbr wired at the top level
    
    def feedthroughs(netlist):
        return sorted(p for p, outs in netlist.items()
                      if outs and all(o.endswith("_out") for o in outs)
                      and "core" not in outs)
    
    assert feedthroughs(bad) == ["irq_sbr_in"], feedthroughs(bad)
    assert feedthroughs(fixed) == [], feedthroughs(fixed)
    # Signal conservation: the rerouted signal still exists, at the top level.
    top_level_nets = set(fixed) | {"irq_sbr_src", "irq_to_intc"}
    assert {"irq_sbr_src", "irq_to_intc"} <= top_level_nets
    print("PASS: bad form has 1 feedthrough (irq_sbr_in); fixed form has 0, nets conserved")

    What the review looks for

    • The boundary signal list fits on one page per partition, with each signal tagged clock, reset, power, protocol or config.

    • Feedthrough count is reported and the target is zero; each remaining one names its removal date.

    • No protocol channel is split: all its signals cross the same boundary in the same place.

    Verify and debug

    Run the port-use audit on every wrapper: elaborate the block, trace each port inward, and flag any port that reaches a top-level output without touching logic. For protocol channels, check bundle completeness at each boundary: an APB crossing with address but no ready signal is a split channel and a hang waiting to happen. When a feedthrough is found, move the wire to the top level and re-run the audit; the count must drop by exactly one with no new ports added.

    Test mode not disabled in mission mode, threaded through functional wrappers. The scan enable or test-mode pin is shared or floating, and the chip stays in scan or shifts randomly. Mechanically: the test signal transited three partitions untouched, so no partition owned its mission-mode state. Tie and strap the test entry at the top level, gate it glitch-free, and verify the mission-mode pull in the pad-ring review.

    If asked to review a partition boundary, ask for the signal list and sort it into the four allowed classes out loud. Anything left over is your finding, and feedthroughs are the classic one.

    Quasi-static configuration deserves care because it looks like a feedthrough but is not: clock-enable bits and power-intent signals are set before traffic and never toggle during it, so they cross boundaries legally provided each is synchronised once at the destination. The test is toggle rate — if the signal can change mid-operation it is a protocol channel and needs the full handshake or FIFO, not a bare synchroniser. Document the toggle assumption beside each config crossing; a later feature that toggles it dynamically reopens the boundary. A logical feedthrough (an RTL port passing through untouched) is a design smell; physical feedthroughs that the floorplan inserts for routing are normal, and should be counted and budgeted rather than banned — see Budgeting Partitions and Their Interfaces. For choosing and documenting quasi-static crossings see Quasi-Static Signals and Configuration.

    Check yourself A test-mode signal transits three partitions untouched. What is wrong and what is the fix?

    It is a feedthrough: three partitions re-verify whenever test logic changes, with no logic inside consuming it. Route it at the top level to each consumer directly, or give each partition its own registered test entry.

    Related topics

    • Flat Versus Hierarchical

    • Next: NanoSoC Partition Rationale

    • RTL: Port List Discipline

    • RTL: Floorplan Hooks and Hierarchy Contracts

    • CDC & RDC: Quasi-Static Signals and Configuration

    Previous

    19 / 289

    Next: NanoSoC Partition Rationale

    Up next

    Up nextNanoSoC Partition Rationale

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error