Difficulty: Hard · Puzzle 5 of 6 · Topic: Verifying CDC & Reset Puzzles
A two-stage shift register has a 2 ns clock-tree skew on the second flop. Design 0 models zero clock-to-q (like RTL); design 3 has a 3 ns clock-to-q. d_in rises at t=1. What do the two qb outputs show at t=10 and t=20, and what is the fix for the failing one?
`timescale 1ns/1ns
module tb;
reg clk = 0;
always #5 clk = ~clk; // posedges at 5, 15, 25
wire clk_b;
assign #2 clk_b = clk; // the second flop's clock arrives 2 ns late (clock-tree skew)
reg d_in = 0;
reg qa0 = 0, qb0 = 0; // design 0: zero clock-to-q
reg qa3 = 0, qb3 = 0; // design 3: 3 ns clock-to-q, as in a real cell
always @(posedge clk) qa0 <= d_in;
always @(posedge clk_b) qb0 <= qa0;
always @(posedge clk) qa3 <= #3 d_in;
always @(posedge clk_b) qb3 <= qa3;
initial begin
#1 d_in = 1;
#9 $display("t=%0d qb(zero clk-to-q)=%b qb(3 ns clk-to-q)=%b", $time, qb0, qb3);
#10 $display("t=%0d qb(zero clk-to-q)=%b qb(3 ns clk-to-q)=%b", $time, qb0, qb3);
#1 $finish;
end
endmoduleDoes the new value of qa arrive before or after the late clock edge of the second flop?
1) Both first flops capture d_in=1 at the edge at t=5. The second flop's clock arrives 2 ns late, at t=7.
2) Design 0: qa0 changes at t=5 (zero delay) and is already 1 when the late edge at t=7 arrives, so qb0 captures the NEW value: qb0=1 at t=10. The data raced through two flops in one clock cycle (a hold violation).
3) Design 3: qa3 changes at t=8, after the late edge at t=7, so qb3 captures the old value 0: qb3=0 at t=10, and 1 after the edge at t=15 (shown at t=20).
4) So at t=10: qb0=1, qb3=0; at t=20: qb0=1, qb3=1. The skew is only harmless if the clock-to-q (plus wire delay) is larger than the skew plus the hold time.
5) RTL and zero-delay gate-level simulation have no clock-to-q, so they show design 0; fix real cases with hold buffers or by balancing the clock tree, and verify with SDF back-annotated gate-level simulation and static hold analysis.Answer: t=10: qb(zero clk-to-q)=1, qb(3 ns clk-to-q)=0; t=20: 1 and 1. The zero-delay model shoots data through when clock skew exceeds clock-to-q (a hold violation); the cure is a hold fix (delay or balanced clock) and checking in SDF gate-level simulation and static timing.
Checked by running the code in Icarus Verilog 13; the printed output supports the answer above. Icarus: zero clock-to-q lets data race through the skewed flop; a 3 ns clock-to-q does not.
Assuming non-blocking assignments protect against skew. They fix zero-delay races within a time step, but an explicit skewed clock (a real delay) puts the capture edge after the NBA update, so the flop captures the new value; the protection exists only while all clocks edge in the same time step.
Which of setup or hold does a slower clock help with? Model answer: setup only (more time to the next edge); a hold violation does not depend on the clock period, so you cannot fix it by slowing the clock; you need to add delay or reduce skew.