Difficulty: Hard · Puzzle 5 of 6 · Topic: Clock Gating & Clock Mux Puzzles
The same clocks and the same request at t=7, but through a switch where each clock has an enable flop on its own falling edge: ena <= ~sel & ~enb (clocked by clka), enb <= sel & ~ena (clocked by clkb), and clk_o = (clka & ena) | (clkb & enb). Initially ena=1, enb=0. List the high pulses of clk_o up to t=26, and say what happens to the switch if clka stops before the falling edge arrives.
`timescale 1ns/1ns
module tb;
reg clka = 0, clkb = 0, sel = 0;
always #5 clka = ~clka; // period 10, rises at 5, 15, 25
always #3 clkb = ~clkb; // period 6, rises at 3, 9, 15, 21, 27
reg ena = 1, enb = 0;
always @(negedge clka) ena <= ~sel & ~enb; // each side may only turn on after the other side is off
always @(negedge clkb) enb <= sel & ~ena;
wire clk_o = (clka & ena) | (clkb & enb);
integer t_r = -1;
always @(clk_o)
if (clk_o) t_r = $time;
else if (t_r >= 0) $display("clk_o high %0d..%0d width=%0d", t_r, $time, $time - t_r);
initial begin
#7 sel = 1; // the same request as before, at t=7
#19 $finish;
end
endmoduleEach enable is updated on the falling edge of its own clock, and enb waits for ena to drop.
1) clka rises at t=5 with ena=1: first pulse 5..10, a full 5 ns. sel=1 arrives at t=7, in the middle of it, and does not touch the output directly.
2) At the falling edge of clka at t=10, ena <= ~sel & ~enb = 0: clka is now disabled, with its pulse already complete.
3) enb changes at the falling edges of clkb (6, 12, 18...). At t=6 sel is still 0; at t=12 enb <= sel & ~ena = 1.
4) clkb then passes: its rising edge at t=15 gives 15..18 and the next one 21..24 (3 ns each). The rising edge at t=9 is ignored, as enb is still 0.
5) If clka stops (stays high or low), its falling edge never comes, ena never drops, enb never rises and the switch hangs: that is why real designs add a bypass or a reset/timeout to force the switch.Answer: clk_o is high 5..10 (width 5), 15..18 (width 3), 21..24 (width 3): no runt, both clocks keep their full pulse widths and there is a dead time of 5 ns, between 10 and 15. If the old clock has stopped, the switch never completes, because the old clock's own falling edge is needed to turn it off.
Checked by running the code in Icarus Verilog 13; the printed output supports the answer above. Icarus: the safe switch produces only full-width pulses; the old pulse completes before the new clock starts.
Looking at the pulse list and stopping there. The switch is glitch-free only because it waits for each clock's own falling edge; the price is a dead time and a dependency on the OLD clock still running. Verification needs a test where the source clock is stopped or very slow.
What is the dead time between the last old-clock edge and the first new-clock edge here? Model answer: the last rising edge is at t=5 and the first of clkb is at t=15, so 10 ns edge to edge (the output itself stays low for 5 ns of that); in general it is bounded by about one period of the old clock plus one of the new one.