Difficulty: Medium · Puzzle 5 of 6 · Topic: Digital Logic Puzzles
Analyze this RTL and state the sequence and period of q. Also identify one synthesis-safe improvement.
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) q <= 3'd0;
else if (q == 3'd5) q <= 3'd0;
else q <= q + 3'd1;
endTrace q values cycle by cycle from reset.
1) Starting from reset q=0.
2) On each clock: 0,1,2,3,4,5 then wrap to 0 (simulated: 0 1 2 3 4 5 0 1 2 3 4 5 0 1).
3) So modulus (period in states) is 6.
4) Values 6 and 7 are unreachable in normal operation, but they are not a trap: the compare is only q==5, so 6 -> 7 -> 0 and 7 -> 0 by the natural 3-bit wrap. Illegal states drain by themselves within 2 cycles.
5) An explicit q>=5 branch would only make that recovery one cycle faster and is easy for formal tools to prove. It does NOT repair X: with q='x the condition is X, the if takes the else branch, and q stays xxx forever (simulated, with and without the q>=5 branch). X is cured only by reset.
6) Real improvements: synchronise the release of rst_n (async assert, sync deassert), register a terminal-count flag instead of decoding q==5 downstream, and give the counter an enable if it is used as a divider.Answer: q cycles 0->1->2->3->4->5->0 with period 6; states 6 and 7 self-recover through the 3-bit wrap, so the useful hardening is a synchronised reset release and a registered terminal-count flag, not an illegal-state branch.
Checked by running the code in Icarus Verilog 13; the printed output supports the answer above. The shown counter simulated in Icarus: 0..5 wrap with period 6, states 6 and 7 drain to 0 by themselves, X stays X with or without the q>=5 branch, and the registered tc matches q==5.
Claiming the extra 'q>5 -> 0' branch rescues X-corrupted state. X in the condition selects the else branch, so q stays X until a real reset; and 6/7 already recover by wrapping.
How would you implement a glitch-free terminal-count pulse for q==5? Model answer: register it so it comes straight from a flop, aligned with q==5: tc <= (q == 3'd4) with the same async reset to 0. A combinational q==5 decode can glitch while several q bits change at once; a flop output cannot.
Starting from reset, q counts zero, one, two, three, four, five and wraps to zero, so the period is six. Values six and seven are unreachable normally, but they recover on their own within two cycles through the three-bit wrap, since the compare is only q equals five. An extra branch for q above five wouldn't fix an X, because the condition is X, the else branch is taken, and q stays X until a real reset. So the useful improvements are a synchronised reset release and a registered terminal-count flag. The trap is claiming the extra branch rescues X-corrupted state.