Detecting Clock Loss
High-availability systems must detect if an external clock source dies and safely switch to an internal backup clock. A clock monitor circuit acts as a watchdog, using a reliable internal clock to supervise an untrusted external clock domain. Because the two clocks are asynchronous, the internal domain cannot sample the external clock directly without risking metastability.
The module monitors clk_ext for activity. A toggle flip-flop operating in the clk_ext domain changes state on every positive edge of clk_ext. This toggle signal is then passed through a standard two-stage synchronizer into the clk_int domain. An edge detector monitors the synchronized signal for any state change by comparing the current synchronized value to its value in the previous cycle. A 4-bit watchdog counter increments every clk_int cycle that no edge is detected. If an edge is detected, the counter resets. If the counter reaches ten, it saturates, and the clock_dead output is asserted.
Timing and Reset Rules
- Clocks:
clk_int(internal reliable clock) andclk_ext(external monitored clock). - Reset:
rst_nis an active-low asynchronous reset applied to all flip-flops in both clock domains. - Toggle Flip-Flop: Changes state on
posedge clk_ext. Resets to 0. - Synchronizer: Two flip-flops clocked on
posedge clk_intsampling the toggle signal. Both reset to 0. - Edge Detector: Requires a third flip-flop on
posedge clk_intto delay the synchronized signal. An edge is detected combinationally when the second synchronizer stage differs from this third stage. - Counter: 4-bit counter clocked on
posedge clk_int. Resets to 0. Increments if no edge is detected. Saturates at 10. - Output:
clock_deadis a combinational output that evaluates to 1 when the counter equals 10, and 0 otherwise.
Worked Trace
Cycle 1: rst_n=0 → all flip-flops 0, counter=0, clock_dead=0 Cycle 2: rst_n=1, clk_ext rises → toggle_q becomes 1 Cycle 3: clk_int rises → sync_q1=1, counter=1 Cycle 4: clk_int rises → sync_q2=1, counter=2. Edge detected (sync_q2 != sync_q3). Cycle 5: clk_int rises → sync_q3=1, counter resets to 0. Edge no longer detected. Cycle 6: clk_int rises → counter=1. Cycles 7-15: clk_ext stays flat. counter increments each clk_int cycle. Cycle 15: counter reaches 10. clock_dead becomes 1.
Diagrams
{ "signal": [
{ "name": "clk_int", "wave": "p.........." },
{ "name": "rst_n", "wave": "01........." },
{ "name": "clk_ext", "wave": "0.1.......0" },
{ "name": "toggle_q", "wave": "0.1........" },
{ "name": "sync_q1", "wave": "0..1......." },
{ "name": "sync_q2", "wave": "0...1......" },
{ "name": "sync_q3", "wave": "0....1....." },
{ "name": "edge_detect","wave": "0...10....." },
{ "name": "counter", "wave": "=.=.=.=.=.=", "data": ["0","1","2","3","0","1"] }
], "head": { "text": "CDC synchronization and edge detection." } }Port Table
| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk_int | input | 1 | Internal reliable clock; positive-edge triggered | | clk_ext | input | 1 | External monitored clock; positive-edge triggered | | rst_n | input | 1 | Asynchronous active-low reset for all domains | | clock_dead | output | 1 | Combinational output; 1 when counter is 10 |
Constraints
- The design must use exactly one flip-flop clocked by
clk_ext. - The synchronizer must use exactly two flip-flops clocked by
clk_int. - The edge detector must use exactly one additional flip-flop clocked by
clk_int. - The counter must not roll over to 11; it must saturate at 10.
- The counter must reset to 0 on the
clk_intpositive edge immediately following an edge detection.
Topics
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.
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.