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 Path
  • CDC/RDC Glossary
  • CDC/RDC Metrics Reference
  • CDC/RDC Interview Prep
  • CDC/RDC Signoff Cheatsheet
  • Clock Domains and Failure Modes8
  • Metastability and Synchronizers16
  • CDC Protocols and Handshakes16
  • Reconvergence and Gray Coding16
  • Reset Domain Crossing16
  • Architecture and Design Rules16
    • CDC-Aware Partitioning
      • Choosing Domain Boundaries
      • Register at the Boundary
      • Minimising Crossings
      • Crossing Inventory
    • Clock Gating and Muxing
    • Interface and IP Rules
    • Quasi-Static Signals and Configuration
  • CDC Signoff Methodology24
  • RDC Signoff16
  • Debug and Case Studies11
  • CDC and RDC Interview Prep30
  • Capstone: Sign Off a Multi-clock Peripheral4
Loading lesson

‹CDC-Aware Partitioning
  1. Topics
  2. CDC & RDC
  3. Architecture and Design Rules
  4. CDC-Aware Partitioning
  5. Register at the Boundary

Part 6 · Architecture and Design Rules · Intermediate

Register at the Boundary

Launch every crossing signal from a flop in its source domain; why a combinational output crossing is a violation.

On this page

    A synchroniser can only tame one uncertainty: when the signal changes relative to the destination clock. It cannot tame a signal that glitches, because a glitch looks exactly like a fast real change. Launching every crossing from a register removes the glitch, leaving the synchroniser one job instead of two.

    The rule

    The driver of a crossing must be the output of a flip-flop in the source domain, with no combinational logic between that flop and the first synchroniser flop. Structural analysis flags anything else, generally under a category like combinational logic before the synchroniser.

    design.sv
    1
    2
    3
    4
    // bad-example
    // a decoded strobe crossed directly: it can glitch when its inputs settle
    assign cross_strobe = (state == 2'b10) && req;
    sync2 u_sync (.clk(clk_d), .d(cross_strobe), .q(strobe_d));

    The comparator output can flicker as state and req settle at slightly different times. The synchroniser faithfully carries the flicker across, and the destination sees a strobe that never existed.

    design.sv
    1
    2
    3
    4
    // snippet
    // register the strobe in the source domain first, then cross the register
    always_ff @(posedge clk_s) cross_strobe_q <= (state == 2'b10) && req;
    sync2 u_sync (.clk(clk_d), .d(cross_strobe_q), .q(strobe_d));

    The registered version changes at most once per source cycle and never glitches. It can still change near a destination edge, which is exactly the case the synchroniser is built for.

    What the checking tools look for

    Check

    What it means

    Source is a flop

    The crossing net traces back to a register output in the source domain, not to combinational logic or a primary input.

    No logic on the path

    No gates sit between the source flop and the first synchroniser flop, or between the synchroniser flops.

    One destination clock

    Every flop of the synchroniser runs on the destination clock.

    Single fanout

    Only the last synchroniser flop drives destination logic; the intermediate flop drives nothing else.

    How to verify it

    Run structural analysis on the whole design and clear every combinational-source finding, either by registering the source or by documenting why the path is provably glitch-free. Then re-check after synthesis, because optimisation can push logic across the boundary that was clean in RTL.

    Common pitfall

    A primary input (a pin or a synchronised signal from a third domain) is not a registered source. Treat inputs as combinational until they have passed through a flop in the source domain.

    Check yourself A crossing is driven by the output of a 4-to-1 mux whose select comes from a counter in the source domain. It feeds a two-flop synchroniser. What is wrong?

    The mux output can glitch when the counter bits settle at different times, and the synchroniser can capture the glitch as a real event. Register the mux output in the source domain and cross the register.

    Related topics

    • Choosing Domain Boundaries

    • RTL: Metastability and Synchronisation

    Previous

    80 / 179

    Next: Minimising Crossings

    Up next

    Up nextMinimising Crossings

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Crossing Inventory