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
    • Clock Gating Architecture
      • ICG Cells and Enable Timing
      • Hierarchical Gating and Enable Ownership
      • Failure: DMA Gated During an APB Access
    • 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

←Clock Gating Architecture
  1. Topics
  2. SoC Design
  3. Clock and Reset Architecture
  4. Clock Gating Architecture
  5. ICG Cells and Enable Timing
On this page

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

    ICG Cells and Enable Timing

    The latch-based integrated clock-gating cell: why the latch exists, what setup and hold it needs, and a model that proves it.

    Why it matters

    Gating a clock with a plain AND gate works until the enable changes while the clock is high, and then it slices a pulse in half. A runt clock corrupts state exactly like a runt mux glitch, but it strikes the block that was trying to save power, so the failure arrives disguised as a functional bug. The integrated clock-gating cell exists to make that slice impossible. This lesson teaches the cell and its timing contract. Its one job is the cell; who drives the enables is next.

    The core idea

    The cell is a level-sensitive latch followed by an AND gate; the circuit treatment lives in the RTL course and is recalled here only as far as the integrator uses it. The latch is transparent while the clock is low and closes at the rising edge, so the AND gate only ever sees its enable change while the clock is low. The gated output therefore produces only full-width pulses and clean stretches of low, provided the enable meets its setup and hold to the latch-closing edge: a setup before and a hold after the rising edge, checked by the clock-gating checks in timing analysis (see Clock Gating Checks). An enable that comes from another clock is not an ICG input yet: the latch is not a synchroniser, so it first goes through a two-flop synchroniser in the gated clock's domain. On NanoSoC the CLK_EN bits are written in clk_per and the gates they drive sit in clk_sys, so each enable crosses exactly that way, one branch of crossing X7. Synthesis infers these cells from coded enable style (see Clock Gating and Low Power); the integrator's job is the enables and their synchronisers, not the transistors. NanoSoC has three block-level gates (clk_cpu, clk_dma, clk_sbr) and the two fast-clock root gates opened at step R4; the two CLK_EN bits need one two-flop synchroniser each.

    nano_icg.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // NanoSoC teaching values: latch-based ICG wrapper. The latch passes en
    // only while clk is low, so gclk shows full pulses and clean low stretches.
    module nano_icg (
      input  logic clk,
      input  logic en,
      input  logic test_en,  // test mode forces the clock on; owned by DFT
      output logic gclk
    );
      logic en_lat;
    
      always_latch begin
        if (!clk) en_lat = en | test_en;
      end
    
      assign gclk = clk & en_lat;
    endmodule

    The model

    The module compiles, which proves the syntax, but the no-runt property needs its own proof: drive the enable so it changes inside a high phase, which is the case a plain AND gate fails, and confirm the gated output still never shows a pulse narrower than a full half-period. The model below mirrors the latch and the AND gate sample by sample and runs the plain AND gate beside it, so the test can fail:

    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
    31
    32
    33
    34
    35
    36
    37
    38
    # Models of the ICG (latch + AND) and of the forbidden plain AND gate.
    # Sample grid: 0,0,1,1 per period, so a full half-period is 2 samples.
    def icg_trace(clk, en):
        gclk, held = [], 0
        for c, e in zip(clk, en):
            if c == 0:
                held = e  # latch transparent while the clock is low
            gclk.append(c & held)
        return gclk
    
    def and_trace(clk, en):
        return [c & e for c, e in zip(clk, en)]
    
    def high_runs(trace):
        runs, n = [], 0
        for v in trace + [0]:
            if v:
                n += 1
            elif n:
                runs.append(n)
                n = 0
        return runs
    
    clk = [0, 0, 1, 1] * 6
    en = [1] * 7 + [0] * 12 + [1] * 5  # changes at index 7 and 19: mid-high
    # The enable really does change inside high phases (the hard case).
    assert clk[7] == 1 and clk[19] == 1
    
    gclk = icg_trace(clk, en)
    bad = and_trace(clk, en)
    # ICG: the pulse containing the change is still full width (indices 6,7),
    # and the high phase containing the rise (18,19) stays low.
    assert gclk[6:8] == [1, 1], gclk[6:8]
    assert gclk[18:20] == [0, 0], gclk[18:20]
    assert all(r >= 2 for r in high_runs(gclk)), high_runs(gclk)
    # Plain AND: the same stimulus gives a runt, so the test discriminates.
    assert any(r < 2 for r in high_runs(bad)), high_runs(bad)
    print("PASS: enable changes mid-high; ICG full width, plain AND runs short")

    What the review looks for

    • Every gated clock in the tree passes through a library ICG cell, never a coded AND gate; the lint report proves it.

    • The enable timing contract is checked per gate, with the test_en override included in the check.

    • The model above, or its equivalent, runs for enables changing at every phase of the clock.

    Verify and debug

    Toggle each enable at random phases in gate-level simulation and watch the gated clock for runt pulses; a pulse shorter than a full half-period convicts the cell or its wiring. If the failure appears only with test_en asserted, the DFT override path is guilty, not the functional enable. For the gating review discipline see Clock gating done right.

    Clock gate enable glitch. Symptom: truncated pulse and state corruption. Caught by lint and by timing clock-gating checks. Fixed by using the library ICG cell and meeting its setup and hold, exactly the contract above.

    If asked why the latch, answer with the phase: the latch holds the enable steady while the clock is high and closes at the rising edge, so the AND gate output can only change while the clock is low. Then name what is checked: setup and hold of the enable to the rising edge.

    Check yourself The enable is generated by logic on the same clock it gates. What must hold for the ICG contract?

    The enable path must meet setup and hold to the rising edge of that clock, where the latch closes. Same-domain generation is the normal case; it still needs the check, because a late enable misses the latch window and the gate opens or closes one cycle later.

    Related topics

    • Next: Hierarchical Gating and Enable Ownership

    • RTL: Safe RTL Gating Style

    • STA: Clock Gating Checks

    Previous

    97 / 289

    Next: Hierarchical Gating and Enable Ownership

    Up next

    Up nextHierarchical Gating and Enable Ownership

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Failure: DMA Gated During an APB Access