A consensus term, a ripple counter, and a bouncing reset
The glue logic of a bench instrument is an 8-bit synchronous block clocked at 50 MHz. One combinational output is F = A'B + AC, implemented as a two-level AND–OR in a CPLD and brought out to a pin that drives, for historical reasons, the asynchronous clock input of a ripple counter. In one operating mode B and C are tied high permanently and A toggles at about 1 kHz. A scope on F shows a clean logic 1 except for a 6 ns low-going notch each time A falls, and the ripple counter over-counts by exactly one per notch. Separately, a front-panel pushbutton is wired directly to the asynchronous reset input of the main state machine; the button bounces for about 2 ms, and after a few weeks in the field the instrument has twice come up in an undefined state after a power interruption. The CPLD vendor's datasheet claims 'glitch-free registered outputs'.
1. Prove that the notch is a static-1 hazard and give the minimal gate-level fix. Then explain why the CPLD tool may silently undo your fix.
Read the worked answer
Proof by Boolean algebra. Put B = C = 1:
F = A'·1 + A·1 = A' + A = 1 for every value of A.
So F should never change when A toggles. But consider A going 1 → 0. The term AC must fall, and the term A'B must rise. The inverter that produces A' adds delay, so for a few nanoseconds the old term has already dropped and the new one has not yet risen: F = 0·1 + 0·1 = 0 briefly.
Karnaugh view. The two product terms A'B and AC occupy adjacent 1-cells in the map (the cells differ only in A), and no single implicant covers both. That is the textbook condition for a static-1 hazard.
Fix. Add the consensus term BC:
F = A'B + AC + BC
With B = C = 1 the added term is 1 throughout the transition, holding F high; for every value of A, F = (A' + A)·1 + BC = 1. The cost is one 2-input AND gate, and the expression is no longer a minimal SOP - deliberately.
Why the tool may remove it. Synthesis minimisers work to a cost function (product terms, macrocells). BC is logically redundant, so an optimiser will delete it or absorb it. You must mark the term as don't-touch / preserve, and re-run static timing after fitting, because the hazard window depends on post-place-and-route delay, not on the source expression.
2. Explain why the notch reaches the counter at all, and give the architectural fix. Is the vendor's 'glitch-free' claim a lie?
Read the worked answer
Why it reaches the counter. Glitches are normal and expected behaviour of combinational logic: any two-level network with reconvergent paths can produce them, and they are harmless as long as nothing samples them at the wrong time. Here the notch is used as a clock edge by the ripple counter, which is an asynchronous element with no notion of a clock period. The counter sees 1 → 0 → 1 on its clock pin and registers an extra count. The fault is therefore architectural, not the hazard itself: a combinational node is being used as a clock.
Fixes, in order of preference:
- Re-implement the ripple counter as a synchronous counter clocked by the same 50 MHz clock, with F feeding a clock enable. One extra flip-flop per stage, and the notch becomes irrelevant because it never coincides with a clock edge in a stable state.
- If the pin must remain a clock, register F in the output macrocell first (registered output mode) so the pin only ever changes on a clock edge. The combinational node inside the device still glitches, but the pin does not.
The vendor claim. It is accurate but narrow: 'glitch-free' applies to registered outputs, where the pin is driven by a flip-flop. The datasheet says nothing about combinational outputs, which can glitch by construction. Reading it as a guarantee about internal nodes is a common and costly misreading.
3. Address the reset problem: the button bounces for 2 ms and the machine occasionally starts in an undefined state. Design the input conditioning and explain the specific timing violations you are preventing.
Read the worked answer
Two distinct problems.
- Bounce. 2 ms of contact chatter at 50 MHz is 100,000 clock periods. A bouncing signal presents many edges to the reset port; each edge is an asynchronous event and each is a chance to violate a timing parameter.
- Asynchronous de-assertion. Even a clean button is asynchronous to the 50 MHz clock. Asserting reset asynchronously is safe and desirable (it works even without a clock), but removing it asynchronously can violate the flip-flop's recovery and removal times. If one flop exits reset on one clock edge and another exits a cycle later, the machine enters an illegal state or a state whose next-state logic was never defined. That is precisely the 'undefined startup' symptom.
Standard fix.
- Synchroniser: two flip-flops in series, clocked by the 50 MHz clock, with the raw button as an asynchronous set/clear on the first stage only. Assertion is asynchronous (immediate, clock-independent); de-assertion is retimed, so the reset releases on a clean clock edge. The second stage gives the first stage a full 20 ns to resolve any metastability.
- Debounce: a counter that requires the synchronised level to be stable for ~20 ms (1,000,000 clocks) before accepting it. Debounce after the synchroniser, not before - filtering a metastable signal with logic just propagates the uncertainty.
- Document the reset tree: one synchroniser per clock domain, and reset removal retimed in every domain that uses it. Do not pass raw reset across domain boundaries.
With this in place, the 2 ms bounce only delays the release; the machine leaves reset on a single, clean clock edge.