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
  • Clock and Reset Architecture24
    • Clock Sources and PLLs
    • Dividers, Muxes and Glitch-Free Switching
      • Integer Dividers and Clock Muxes
      • Glitch-Free Switching Sequence
      • Switching Failure Modes
    • Clock Gating Architecture
    • Clock Domain Planning
    • Top-Level Crossings
    • Always-On Domain, Wake Policy and a Timer Extension
    • Reset Sources and Reset Tree
    • Reset Sequencing and Release
  • 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

←Dividers, Muxes and Glitch-Free Switching
  1. Topics
  2. SoC Design
  3. Clock and Reset Architecture
  4. Dividers, Muxes and Glitch-Free Switching
  5. Integer Dividers and Clock Muxes
On this page

    Part 5 of 14, lesson 4 of 24Part 5 of 14/Clock and Reset Architecture/Lesson 4 of 24All levels

    Integer Dividers and Clock Muxes

    Divide-by-4 and divide-by-8 from one VCO: counters, 50 percent duty cycle, aligned edges and what muxes select.

    Why it matters

    The dividers are the quietest blocks in the tree and the easiest to get subtly wrong. A divide-by-8 built as three toggle flip-flops in series (a ripple divider) still divides exactly by 8, but each stage is clocked by the previous stage's output, so its edges arrive up to three clk-to-q delays after the VCO edge and are skewed against the divide-by-4 chain; the phase relation the domain plan relies on is gone. On NanoSoC both dividers count from the same 768 MHz VCO, so every clk_sys rising edge, one every 10.417 ns, coincides with a clk_cpu rising edge. This lesson states what coincides and what does not, because the crossing inventory depends on it. Its one job is the dividers and the tree's lack of a runtime mux; the switching sequence is next.

    The core idea

    An integer divider is a counter that toggles its output every N VCO edges for a divide by N, using both clock phases where an even divide must keep 50 percent duty cycle. Divide by 4 toggles every 2 VCO edges; divide by 8 toggles every 4. Because both counters see the same VCO edge, every rising edge of clk_sys coincides with a rising edge of clk_cpu (every 10.417 ns, with two clk_cpu edges per clk_sys period). The crystal clock is the PLL's reference, so the ratios are exact, 8 : 4 : 1, and the clocks do not drift apart. But the phase between clk_per and the divided clocks at the flops depends on the PLL feedback path, the divider reset and the separate clock trees: it is fixed in time but neither known nor bounded by the design, so signoff treats clk_per as asynchronous to both. Do not read the fact that every eighth clk_cpu edge corresponds to one clk_per edge as alignment: the edge count is exact, the offset is unbounded.

    NanoSoC as specified has no runtime clock mux: clk_per is the crystal itself, wired directly past the PLL, and the two fast clocks have fixed ratios. A real chip usually adds muxes at the roots (a test clock against the functional clock, PLL against bypass); those are a teaching extension here, not part of NanoSoC. Wherever such a mux exists, its select needs an owner and a reset value, and it is constrained so the analysis tools use the right clock per mode. For constraining dividers and muxes see Generated Clocks & Dividers and the constraint merge itself belongs to IP integration.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    VCO = 768e6
    CPU_DIV, SYS_DIV = 4, 8
    cpu, sys, per = VCO / CPU_DIV, VCO / SYS_DIV, 24e6
    
    def rising_edges_in_vco_ticks(div, ticks):
        # A divider that toggles every div/2 VCO edges rises once per div ticks.
        return {t for t in range(0, ticks, div)}
    
    SYS_PERIOD_TICKS = SYS_DIV  # one sys period in VCO ticks
    cpu_edges = rising_edges_in_vco_ticks(CPU_DIV, 64)
    sys_edges = rising_edges_in_vco_ticks(SYS_DIV, 64)
    # Every sys rising edge coincides with a cpu rising edge (same VCO count).
    assert sys_edges <= cpu_edges
    # Two cpu edges per sys period, so half of the cpu edges are alone.
    assert len(cpu_edges) == 2 * len(sys_edges)
    assert abs(1e9 / sys - 10.4167) < 1e-3  # coincidence period in ns
    # Crystal clock: frequency ratios only (VCO edges per crystal period = 32).
    assert round(VCO / per) == 32 and round(cpu / per) == 8 and round(sys / per) == 4
    # A wrong divider (/5 instead of /4) breaks the coincidence: the test can fail.
    assert not (rising_edges_in_vco_ticks(SYS_DIV, 64) <= rising_edges_in_vco_ticks(5, 64))
    print("PASS: cpu/sys edges coincide every 10.417 ns; crystal shares only the 8:4:1 ratios")

    What the review looks for

    • Both dividers count the same VCO edge, stated in the design, not assumed from the ratio.

    • Every mux select has an owner, a reset value and a timing-analysis mode that matches it.

    • Duty cycle is specified where gated clocks need it: a halved duty cycle breaks the enable-timing budget downstream.

    Verify and debug

    Measure the coincidence on the bench: trigger on a clk_sys rising edge and confirm a clk_cpu rising edge under it, then confirm that the offset to clk_per is not something the design promises. A divider that occasionally slips points at its reset: both counters must come out of reset together, or the alignment starts with a permanent offset. That reset-together rule returns in the reset tree topic.

    Wrong synchronous assumption: two clocks at related frequencies from different divider trees treated as synchronous. The symptom is setup and hold failures with uncontrolled skew that pass in zero-delay simulation and fail in silicon. The fix is to declare the pair asynchronous and cross it properly; on NanoSoC the CPU-to-system crossings use FIFOs even though both clocks come from one PLL.

    If asked whether clk_cpu and clk_sys are synchronous, answer both halves: phase-related by construction from one VCO, but signed off as asynchronous because they leave through separate roots and separate trees. Then name the FIFO that follows from the second half.

    Check yourself Why must both dividers reset together, and what breaks if only one does?

    The coincidence of their edges is what makes the clocks phase-related. If one counter starts a VCO cycle late, every edge pair carries that offset forever, and any logic that assumed alignment, such as a testbench that samples one clock on the other's edge, samples one VCO cycle off.

    Related topics

    • Next: Glitch-Free Switching Sequence

    • STA: Generated Clocks and Dividers

    • RTL: Glitch-Free Clock Mux

    Previous

    91 / 289

    Next: Glitch-Free Switching Sequence

    Up next

    Up nextGlitch-Free Switching Sequence

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Switching Failure Modes