CodiodeCodiode
Home
Problem Solving
Skill Tracks
My Assignments
Contests
Leaderboard
Community
Settings
Codiode/Problems/Sequential Logic

Automatic Clock Gating Based on Idle Signal

HardVerilog / SystemVerilogBuild

Modern System-on-Chip (SoC) designs rely heavily on architectural clock gating to reduce dynamic power. Synthesis tools can automatically insert Integrated Clock Gating (ICG) cells if the RTL is written such that an entire block of registers shares a common enable condition.

A protocol framing engine computes an XOR-based checksum (crc) over an incoming packet. The entire engine must freeze when the system asserts an idle signal, allowing the synthesis tool to extract a single clock gating condition for the entire module.

  • Clock edge: Positive edge of clk.
  • Reset: Asynchronous active-low rst_n. On reset, state becomes 0, crc becomes 0, and valid_out becomes 0.
  • Priority: idle has the highest priority after reset. When idle is 1, all registers hold their exact previous values, ignoring all other inputs.
  • Output registers: All outputs (state, crc, valid_out) are registered and update strictly on the positive clock edge.
  • FSM behaviour on an active clock edge (idle is 0):
  • WAIT_SOF (2'b00): If sof is 1, state becomes PAYLOAD (2'b01), crc becomes data_in, and valid_out becomes 1. If sof is 0, state remains WAIT_SOF, crc becomes 0, and valid_out becomes 0.
  • PAYLOAD (2'b01): If eof is 1, state becomes DONE (2'b10) and valid_out becomes 0. If eof is 0, state remains PAYLOAD and valid_out remains 1. Regardless of eof, crc becomes the bitwise XOR of its current value and data_in.
  • DONE (2'b10): state unconditionally becomes WAIT_SOF. crc retains its current value. valid_out remains 0.

Worked Trace: Cycle 1: rst_n=0 → state=0, crc=0, valid_out=0 Cycle 2: rst_n=1, idle=1, sof=1, data_in=8'hAA → state=0, crc=0, valid_out=0 (frozen, ignores sof) Cycle 3: idle=0, sof=1, data_in=8'hAA → state=1, crc=8'hAA, valid_out=1 (enters PAYLOAD) Cycle 4: idle=0, sof=0, data_in=8'h55 → state=1, crc=8'hFF, valid_out=1 (CRC is AA ^ 55) Cycle 5: idle=1, eof=1, data_in=8'h11 → state=1, crc=8'hFF, valid_out=1 (frozen, ignores eof) Cycle 6: idle=0, eof=1, data_in=8'h0F → state=2, crc=8'hF0, valid_out=0 (enters DONE, CRC is FF ^ 0F) Cycle 7: idle=0, eof=0, data_in=8'h00 → state=0, crc=8'hF0, valid_out=0 (enters WAIT_SOF, CRC holds value from DONE) Cycle 8: idle=0, sof=0, data_in=8'h00 → state=0, crc=8'h00, valid_out=0 (clears CRC in WAIT_SOF)

flowchart LR
    RESET(( )) -->|reset| WAIT
    WAIT((WAIT_SOF)) -->|sof=1| PAYLOAD
    WAIT -->|sof=0| WAIT
    PAYLOAD((PAYLOAD)) -->|eof=1| DONE
    PAYLOAD -->|eof=0| PAYLOAD
    DONE((DONE)) -->|unconditional| WAIT
{ "signal": [
  { "name": "clk",       "wave": "p......." },
  { "name": "rst_n",     "wave": "01......" },
  { "name": "idle",      "wave": "x1001000" },
  { "name": "sof",       "wave": "x1100000" },
  { "name": "eof",       "wave": "x0001100" },
  { "name": "data_in",   "wave": "x=======", "data": ["AA", "AA", "55", "11", "0F", "00", "00"] },
  {},
  { "name": "state",     "wave": "0.1..20." },
  { "name": "crc",       "wave": "====.===", "data": ["00", "00", "AA", "FF", "F0", "F0", "00"] },
  { "name": "valid_out", "wave": "0.1..0.." }
], "head": { "text": "FSM operation showing idle freezing and CRC accumulation." } }

| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset; all registers go to 0 | | idle | input | 1 | Active-high clock gate enable; freezes all registers when 1 | | sof | input | 1 | Start of frame indicator | | eof | input | 1 | End of frame indicator | | data_in | input | 8 | Incoming packet byte | | state | output | 2 | Current FSM state | | crc | output | 8 | Accumulated XOR checksum | | valid_out | output | 1 | High during active payload processing |

Constraints

  • All registers must update on the positive edge of clk. Reset is asynchronous and active-low.
  • state, crc, and valid_out must reset to 0.
  • The idle signal takes strict priority over all other synchronous inputs. When idle is 1, no registers may change state.
  • The RTL must be structured so that a single if (!idle) condition encloses all state updates, allowing inference of a single clock gating cell.

Topics

FSMClock Domain CrossingLow PowerClock Gating

Solve this problem

Write the module in Verilog, SystemVerilog or VHDL. Your submission is compiled and simulated against a real testbench — you get the waveform back, not a stored answer.

This problem is part of Codiode Pro. The statement above is free to read.

Sign in to solveSee what Pro unlocks

The circuit builder and code editor need a desktop screen. On a phone, read the problem here and open it on a laptop to solve.

Related problems

  • Basic D Flip FlopEasy
  • Debug: Missing Edge in Sensitivity ListMedium
  • Read After Write Hazard DetectionEasy
  • Parameterized Interface with ModportsHard
  • Struct Array PipelineHard
  • T Flip Flop from D Flip Flop TemplateEasy
  • Recursive Generate Reduction TreeHard
  • Four Stage Shift RegisterEasy

Browse all problems · Learning tracks