Skip to content

3.8 Hazards and how to avoid them

Why this matters

A circuit can be correct on paper and still put out the wrong value for a few gate delays after an input changes. Most of the time nobody notices. But if that output sets a flag, starts a motor, or is watched by a circuit that does not wait for a clock, a one-instant blip is as good as a real event. A K-map tells you ahead of time which single-input changes are at risk, and which extra group removes the risk.

  • Decide from a K-map whether a sum of products has a static-1 hazard, and name the input change that causes it.
  • Add the group that removes a static-1 hazard, and show that the new circuit computes the same function.
  • Tell a hazard, which is a property of a circuit, from a glitch, which is what one set of gate delays actually does.
  • Apply the same idea to a product of sums, where the risk is a static-0 hazard.
  • Explain what a hazard-free circuit costs, and why a clocked design can often ignore a glitch.

Intuition

Think of a relay race in which the output is the baton. While one runner holds it, one product term is 1. When the race moves on, that runner hands the baton to a second one. If the first lets go a moment before the second has a grip, the baton hits the ground and the output dips to 0 for an instant, although the function asked for no such thing. The cure is a third runner who holds the baton through the whole change. That runner is redundant when everything goes smoothly, and matters only during the hand-off.

This is the autopilot circuit of Section 3.3, described again here with the same signal and net names so that this section stands on its own. A plane's autopilot should engage when whoever is in charge asks for it. The copilot's request is CAR (copilot autopilot request). The pilot's request is PAR (pilot autopilot request). The signal PIC (pilot in charge) is 1 when the pilot is in charge and 0 when the copilot is. The output AE (autopilot engaged) is 1 when the person in charge is asking.

That gives CAR⋅PIC‾+\mathrm{CAR} \cdot \overline{\mathrm{PIC}} + PAR⋅PIC\mathrm{PAR} \cdot \mathrm{PIC}. It is a minimal sum of products: two AND gates feeding one OR gate, with a NOT gate that makes PIC‾\overline{\mathrm{PIC}} for the copilot's gate. A NOT on an input does not count as a level.

Schematic ch03/s08-autopilot-minCARPICPARAEpic_n

A logic schematic with inputs CAR, PIC and PAR and output AE.

NOT gate g_not: input PIC; output n1.

AND gate g_copilot: inputs CAR and n1; output n2.

AND gate g_pilot: inputs PIC and PAR; output n3.

OR gate g_engage: inputs n2 and n3; output AE.

It agrees with the function logic:ch03/s08-autopilot#AE.

Description: A NOT gate takes PIC. The top AND gate takes CAR and the NOT gate's output, the bottom AND gate takes PIC and PAR, and an OR gate combines the two AND outputs into AE.

Figure 3.8.1. The minimal circuit. The NOT gate's output is labelled pic_n.

How CSE 369 writes this

On a three-variable map the columns are the first two variables in Gray order and the row variable is the third, as in the section on grouping. Here the inputs are listed CAR, PAR, PIC, so CAR and PAR label the columns and PIC labels the rows. That puts the pair of cells that matter in this section in one column.

Example 3.8.1(where the hazard hides).
Karnaugh map of AE: columns CAR,PAR, rows PIC00110110CAR,PARPIC0001111001

AE = CAR⋅PIC‾+PAR⋅PIC\mathrm{CAR} \cdot \overline{\mathrm{PIC}} + \mathrm{PAR} \cdot \mathrm{PIC}

Static-1 hazard: CAR=1 PAR=1 PIC=0 and CAR=1 PAR=1 PIC=1 (only PIC changes) are held together by no single group.

  • CAR⋅PIC‾\mathrm{CAR} \cdot \overline{\mathrm{PIC}}horizontal pair: row 0, columns 11 and 10 (2 cells)
  • PAR⋅PIC\mathrm{PAR} \cdot \mathrm{PIC}horizontal pair: row 1, columns 01 and 11 (2 cells)
Karnaugh map of AE: columns CAR,PAR, rows PIC; cell values are 0, 1 or X for don't care
CARPAR=00CARPAR=01CARPAR=11CARPAR=10
PIC=00011
PIC=10110

Groups drawn:

  1. CAR and not PIC: horizontal pair in row PIC=0, columns CAR,PAR=11 and 10; 2 cells.
  2. PAR and PIC: horizontal pair in row PIC=1, columns CAR,PAR=01 and 11; 2 cells.

Description: A three-variable Karnaugh map with columns CAR and PAR and rows PIC, showing two groups of two cells, one in each row.

Figure 3.8.2. The minimal cover of AE: one group in each row.

The map in Figure 3.8.2 has four 1s. The horizontal pair in row PIC=0, columns CAR,PAR=11 and 10 is the copilot's AND gate: its term is CAR⋅PIC‾\mathrm{CAR} \cdot \overline{\mathrm{PIC}}. The horizontal pair in row PIC=1, columns CAR,PAR=01 and 11 is the pilot's AND gate: its term is PAR⋅PIC\mathrm{PAR} \cdot \mathrm{PIC}.

Now look at the cell where CAR, PAR and PIC are 1, 1, 0 and the cell where they are 1, 1, 1. They are neighbors: they differ only in PIC. Both are 1, so when CAR and PAR stay at 1 and PIC changes, AE should stay at 1. But the first cell belongs only to the copilot's group, and the second only to the pilot's. The vertical pair in column CAR,PAR=11 would hold both of them, and the circuit has no gate for it. So a change in PIC has to pass the baton from one AND gate to the other.

A hazard is a possibility, a glitch is an event

Section titled “A hazard is a possibility, a glitch is an event”

Section 3.3 defined a glitch as a short, unwanted pulse and found one in this circuit. Whether a glitch happens in a real circuit depends on its gate delays, which are never exactly equal. So the useful word for a design is not "glitch" but this one:

Definition 3.8.1(static hazard).

A circuit has a static-1 hazard for a single input change when the output should stay at 1 before and after the change, and some choice of gate delays would make it dip to 0 in between. A static-0 hazard is the mirror image: the output should stay at 0, and some choice of delays would make it spike to 1.

Definition 3.8.2(dynamic hazard).

A dynamic hazard is the case where the output should change once, and some choice of delays would make it change three or more times.

A hazard belongs to the circuit and to the input change. A glitch is one outcome that one set of delays can produce. These are the delays of Exercise 3.3.1, where you traced the same dip in the same circuit with the same net names, and this section asks what the dip says about the map. The next figure simulates the minimal circuit with gate delays, CAR and PAR held at 1, and PIC first falling and then rising. The NOT gate is made slower than the AND and OR gates, so the effect is two columns wide; the delays are in the listing in the next section.

Waveform ch03/autopilot-min-glitch: CAR, PAR, PIC, dut.pic_n, dut.via_copilot, dut.via_pilot, AECARPARPICdut.pic_ndut.via_copilotdut.via_pilotAE90100110120130140150160170180190time (ps)Waveform ch03/autopilot-min-glitch: CAR, PAR, PIC, dut.pic_n, dut.via_copilot, dut.via_pilot, AECARPARPICdut.pic_ndut.via_copilotdut.via_pilotAE90100110120130140150160170180190time (ps)Waveform ch03/autopilot-min-glitch: CAR, PAR, PIC, dut.pic_n, dut.via_copilot, dut.via_pilot, AECARPARPICdut.pic_ndut.via_copilotdut.via_pilotAE90110130150170190time (ps)Waveform ch03/autopilot-min-glitch: CAR, PAR, PIC, dut.pic_n, dut.via_copilot, dut.via_pilot, AECARPARPICdut.pic_ndut.via_copilotdut.via_pilotAE90110130150170190time (ps)Waveform ch03/autopilot-min-glitch: CAR, PAR, PIC, dut.pic_n, dut.via_copilot, dut.via_pilot, AECARPARPICdut.pic_ndut.via_copilotdut.via_pilotAE90110130150170190time (ps)

Time in ps; one column is 10 ps.

Timing diagram from simulation, ch03/autopilot-min-glitch: time in ps from 90 to 200, 11 columns of 10 ps.

CAR: 1 at 90, no changes.

PAR: 1 at 90, no changes.

PIC: 1 at 90, then 0 at 100, 1 at 160.

dut.pic_n: 0 at 90, then 1 at 120, 0 at 180.

dut.via_copilot: 0 at 90, then 1 at 130, 0 at 190.

dut.via_pilot: 1 at 90, then 0 at 110, 1 at 170.

AE: 1 at 90, then 0 at 120, 1 at 140.

Description: A timing diagram of CAR, PAR, PIC, pic_n, via_copilot, via_pilot and AE. After PIC falls, via_pilot falls first, via_copilot rises later, and AE dips to 0 between them.

Figure 3.8.3. The minimal circuit with gate delays. Lanes that start with dut. are nets inside the circuit.

Read the figure from PIC downward; the text drops the dut. prefix that marks the nets inside the circuit. When PIC falls, via_pilot (the output of the pilot's AND gate) falls one AND delay later. The change has to go through the NOT first to reach the other gate, so pic_n rises later still, and via_copilot rises one AND delay after that. In the gap between them both inputs of the OR gate are 0. AE falls one OR delay after via_pilot falls, and rises one OR delay after via_copilot rises, so the dip lasts as long as the NOT gate's delay does in this model: two columns.

When PIC rises again, the pilot's AND gate turns on while the copilot's is still turning off. With these delays the two terms overlap instead of leaving a gap, and AE does not move. Different delays could swap which direction leaves the gap. The hazard is the possibility; this figure shows one glitch that one set of delays produces, in one direction. A zero-delay simulation of this circuit shows nothing at AE, so it cannot tell you whether a hazard exists.

IntuitionThe test for a static-1 hazard

Take a two-level sum-of-products circuit: AND gates feeding one OR gate, with NOT gates allowed on the inputs. Look at every pair of adjacent 1 cells, that is, every single-input change that should leave the output at 1. If some single group of the cover contains both cells, that group's AND gate stays at 1 through the change and the output cannot dip. If no single group contains both cells, the circuit has a static-1 hazard for that change.

The statement has three qualifiers: the circuit is two-level, only one input changes at a time, and the check is about the cover, the groups that are actually built. Watch the wording too. In the example the two cells are in different groups, but that is not why there is a hazard; the hazard is that no group holds both. After the fix below the same two cells are still in different groups, and the circuit is safe, because a third group holds both.

The fix follows from the test: add the group that holds the uncovered pair. The pair is the cells where CAR and PAR are 1 and PIC changes, and the group that holds it has the term CAR⋅PAR\mathrm{CAR} \cdot \mathrm{PAR}, since PIC changes inside the group and drops out.

Karnaugh map of AE: columns CAR,PAR, rows PIC00110110CAR,PARPIC0001111001

AE = CAR⋅PIC‾+PAR⋅PIC+CAR⋅PAR\mathrm{CAR} \cdot \overline{\mathrm{PIC}} + \mathrm{PAR} \cdot \mathrm{PIC} + \mathrm{CAR} \cdot \mathrm{PAR}

Hazard-free for single input changes: every pair of adjacent 1 cells is held by one drawn group.

  • CAR⋅PIC‾\mathrm{CAR} \cdot \overline{\mathrm{PIC}}horizontal pair: row 0, columns 11 and 10 (2 cells)
  • PAR⋅PIC\mathrm{PAR} \cdot \mathrm{PIC}horizontal pair: row 1, columns 01 and 11 (2 cells)
  • CAR⋅PAR\mathrm{CAR} \cdot \mathrm{PAR}vertical pair: column 11 (2 cells)
Karnaugh map of AE: columns CAR,PAR, rows PIC; cell values are 0, 1 or X for don't care
CARPAR=00CARPAR=01CARPAR=11CARPAR=10
PIC=00011
PIC=10110

Groups drawn:

  1. CAR and not PIC: horizontal pair in row PIC=0, columns CAR,PAR=11 and 10; 2 cells.
  2. PAR and PIC: horizontal pair in row PIC=1, columns CAR,PAR=01 and 11; 2 cells.
  3. CAR and PAR: vertical pair in column CAR,PAR=11; 2 cells.

Description: The same three-variable Karnaugh map with three groups: the two earlier pairs and a vertical pair in the column where CAR and PAR are both 1.

Figure 3.8.4. The hazard-free cover: the two earlier groups and the group in which PIC changes.

This group is called a redundant group, because the other two already cover both of its cells. It is also called the consensus term of the other two: when one term holds a variable (here PIC) and another holds its complement, the product of what remains of each, here CAR and PAR, can be added without changing the function. Because it covers no new 1, adding it does not change the function, and the check below confirms that on all eight inputs:

CAR⋅PIC‾+\mathrm{CAR} \cdot \overline{\mathrm{PIC}} + PAR⋅PIC\mathrm{PAR} \cdot \mathrm{PIC} =CAR⋅PIC‾+= \mathrm{CAR} \cdot \overline{\mathrm{PIC}} + PAR⋅PIC+\mathrm{PAR} \cdot \mathrm{PIC} + CAR⋅PAR\mathrm{CAR} \cdot \mathrm{PAR}
Schematic ch03/s08-autopilot-safeCARPICPARAE

A logic schematic with inputs CAR, PIC and PAR and output AE.

NOT gate g_not: input PIC; output n1.

AND gate g_copilot: inputs CAR and n1; output n2.

AND gate g_pilot: inputs PIC and PAR; output n3.

AND gate g_both: inputs CAR and PAR; output n4.

OR gate g_engage: inputs n2, n3 and n4; output AE.

It agrees with the function logic:ch03/s08-autopilot#AE.

Description: The minimal circuit with a third AND gate at the bottom that takes CAR and PAR, and a three-input OR gate that combines all three AND outputs into AE.

Figure 3.8.5. The hazard-free circuit: one more AND gate, and an OR gate with three inputs.

The new AND gate sees only CAR and PAR, and neither changes, so its output stays at 1 through the whole change. The OR gate always has a 1 on one input.

Waveform ch03/autopilot-safe-clean: CAR, PAR, PIC, dut.pic_n, dut.via_copilot, dut.via_pilot, dut.both_ask, AECARPARPICdut.pic_ndut.via_copilotdut.via_pilotdut.both_askAE90100110120130140150160170180190time (ps)Waveform ch03/autopilot-safe-clean: CAR, PAR, PIC, dut.pic_n, dut.via_copilot, dut.via_pilot, dut.both_ask, AECARPARPICdut.pic_ndut.via_copilotdut.via_pilotdut.both_askAE90100110120130140150160170180190time (ps)Waveform ch03/autopilot-safe-clean: CAR, PAR, PIC, dut.pic_n, dut.via_copilot, dut.via_pilot, dut.both_ask, AECARPARPICdut.pic_ndut.via_copilotdut.via_pilotdut.both_askAE90110130150170190time (ps)Waveform ch03/autopilot-safe-clean: CAR, PAR, PIC, dut.pic_n, dut.via_copilot, dut.via_pilot, dut.both_ask, AECARPARPICdut.pic_ndut.via_copilotdut.via_pilotdut.both_askAE90110130150170190time (ps)Waveform ch03/autopilot-safe-clean: CAR, PAR, PIC, dut.pic_n, dut.via_copilot, dut.via_pilot, dut.both_ask, AECARPARPICdut.pic_ndut.via_copilotdut.via_pilotdut.both_askAE90110130150170190time (ps)

Time in ps; one column is 10 ps.

Timing diagram from simulation, ch03/autopilot-safe-clean: time in ps from 90 to 200, 11 columns of 10 ps.

CAR: 1 at 90, no changes.

PAR: 1 at 90, no changes.

PIC: 1 at 90, then 0 at 100, 1 at 160.

dut.pic_n: 0 at 90, then 1 at 120, 0 at 180.

dut.via_copilot: 0 at 90, then 1 at 130, 0 at 190.

dut.via_pilot: 1 at 90, then 0 at 110, 1 at 170.

dut.both_ask: 1 at 90, no changes.

AE: 1 at 90, no changes.

Description: A timing diagram like the earlier one, with an extra lane both_ask that stays at 1. AE stays at 1 the whole time.

Figure 3.8.6. The hazard-free circuit with the same delays and the same stimulus as before.

Compare it with Figure 3.8.3. The lanes via_pilot and via_copilot do exactly what they did before, including the gap in which both are 0. The new lane both_ask stays at 1, and AE never leaves 1.

The price is one more AND gate and a wider OR gate. The result is no longer a minimal sum of products, because it has three terms where the minimum has two. A minimal circuit and a hazard-free circuit are different goals, and a problem should say which one it wants.

A product-of-sums circuit, OR gates feeding one AND gate, has the mirror problem. The output of a product of sums is 0 when some sum is 0, so the hand-off to watch is between two sums that are 0 in adjacent cells of the off set. If no single sum is 0 in both cells, the output can spike to 1 between them, a static-0 hazard.

Take (A+B)⋅(B‾+C)(A + B) \cdot (\overline{B} + C). To see its zeros as groups, draw the map of its complement (drawn as Gn), where each 0 of G is a 1.

Karnaugh map of Gn: columns AB, rows C11101000ABC0001111001

Gn = A‾ B‾+BC‾+A‾ C‾\overline{A}\,\overline{B} + B\overline{C} + \overline{A}\,\overline{C}

Hazard-free for single input changes: every pair of adjacent 1 cells is held by one drawn group.

  • A‾ B‾\overline{A}\,\overline{B}vertical pair: column 00 (2 cells)
  • BC‾B\overline{C}horizontal pair: row 0, columns 01 and 11 (2 cells)
  • A‾ C‾\overline{A}\,\overline{C}horizontal pair: row 0, columns 00 and 01 (2 cells)
Karnaugh map of Gn: columns AB, rows C; cell values are 0, 1 or X for don't care
AB=00AB=01AB=11AB=10
C=01110
C=11000

Groups drawn:

  1. not A and not B: vertical pair in column AB=00; 2 cells.
  2. B and not C: horizontal pair in row C=0, columns AB=01 and 11; 2 cells.
  3. not A and not C: horizontal pair in row C=0, columns AB=00 and 01; 2 cells.

Description: A three-variable Karnaugh map of the complement of G with three groups of two cells.

Figure 3.8.7. The map of the complement of G, with its two minimal groups and the group that holds the pair they miss.

The vertical pair in column AB=00 corresponds to the sum A+BA + B, which is 0 exactly there. The horizontal pair in row C=0, columns AB=01 and 11 corresponds to the sum B‾+C\overline{B} + C. The two cells where A and C are 0 and B changes are neighbors, and neither of those two groups holds both. The group that does, the horizontal pair in row C=0, columns AB=00 and 01, corresponds to the sum A+CA + C. Adding that sum gives (A+B)⋅(B‾+C)⋅(A+C)(A + B) \cdot (\overline{B} + C) \cdot (A + C), and the check agrees that it is the same function: (A+B)⋅(B‾+C)(A + B) \cdot (\overline{B} + C) =(A+B)⋅(B‾+C)⋅(A+C)= (A + B) \cdot (\overline{B} + C) \cdot (A + C).

The simulations use the same gate delays as before (NOT slower than the rest), with A and C at 0 and B rising and then falling.

Waveform ch03/pos-g-glitch: A, B, C, dut.b_n, dut.sum_ab, dut.sum_bc, GABCdut.b_ndut.sum_abdut.sum_bcG90100110120130140150160170180190time (ps)Waveform ch03/pos-g-glitch: A, B, C, dut.b_n, dut.sum_ab, dut.sum_bc, GABCdut.b_ndut.sum_abdut.sum_bcG90100110120130140150160170180190time (ps)Waveform ch03/pos-g-glitch: A, B, C, dut.b_n, dut.sum_ab, dut.sum_bc, GABCdut.b_ndut.sum_abdut.sum_bcG90110130150170190time (ps)Waveform ch03/pos-g-glitch: A, B, C, dut.b_n, dut.sum_ab, dut.sum_bc, GABCdut.b_ndut.sum_abdut.sum_bcG90110130150170190time (ps)Waveform ch03/pos-g-glitch: A, B, C, dut.b_n, dut.sum_ab, dut.sum_bc, GABCdut.b_ndut.sum_abdut.sum_bcG90110130150170190time (ps)

Time in ps; one column is 10 ps.

Timing diagram from simulation, ch03/pos-g-glitch: time in ps from 90 to 200, 11 columns of 10 ps.

A: 0 at 90, no changes.

B: 0 at 90, then 1 at 100, 0 at 160.

C: 0 at 90, no changes.

dut.b_n: 1 at 90, then 0 at 120, 1 at 180.

dut.sum_ab: 0 at 90, then 1 at 110, 0 at 170.

dut.sum_bc: 1 at 90, then 0 at 130, 1 at 190.

G: 0 at 90, then 1 at 120, 0 at 140.

Description: A timing diagram of A, B, C, b_n, sum_ab, sum_bc and G. After B rises, G rises to 1 for two columns and then falls back to 0.

Figure 3.8.8. The product of sums with gate delays: G spikes to 1 after B rises.
Waveform ch03/pos-g-safe-clean: A, B, C, dut.b_n, dut.sum_ab, dut.sum_bc, dut.sum_ac, GABCdut.b_ndut.sum_abdut.sum_bcdut.sum_acG90100110120130140150160170180190time (ps)Waveform ch03/pos-g-safe-clean: A, B, C, dut.b_n, dut.sum_ab, dut.sum_bc, dut.sum_ac, GABCdut.b_ndut.sum_abdut.sum_bcdut.sum_acG90100110120130140150160170180190time (ps)Waveform ch03/pos-g-safe-clean: A, B, C, dut.b_n, dut.sum_ab, dut.sum_bc, dut.sum_ac, GABCdut.b_ndut.sum_abdut.sum_bcdut.sum_acG90110130150170190time (ps)Waveform ch03/pos-g-safe-clean: A, B, C, dut.b_n, dut.sum_ab, dut.sum_bc, dut.sum_ac, GABCdut.b_ndut.sum_abdut.sum_bcdut.sum_acG90110130150170190time (ps)Waveform ch03/pos-g-safe-clean: A, B, C, dut.b_n, dut.sum_ab, dut.sum_bc, dut.sum_ac, GABCdut.b_ndut.sum_abdut.sum_bcdut.sum_acG90110130150170190time (ps)

Time in ps; one column is 10 ps.

Timing diagram from simulation, ch03/pos-g-safe-clean: time in ps from 90 to 200, 11 columns of 10 ps.

A: 0 at 90, no changes.

B: 0 at 90, then 1 at 100, 0 at 160.

C: 0 at 90, no changes.

dut.b_n: 1 at 90, then 0 at 120, 1 at 180.

dut.sum_ab: 0 at 90, then 1 at 110, 0 at 170.

dut.sum_bc: 1 at 90, then 0 at 130, 1 at 190.

dut.sum_ac: 0 at 90, no changes.

G: 0 at 90, no changes.

Description: A timing diagram like the previous one with an extra lane sum_ac that stays at 0. G stays at 0 the whole time.

Figure 3.8.9. With the extra sum, G stays at 0.

When B rises, sum_ab turns on one OR delay later, but sum_bc stays on until the NOT has acted and one more OR delay has passed. During that gap both sums are 1, and the AND gate puts out a 1. When B falls again there is no overlap, and G stays at 0. In the second figure sum_ac stays at 0 throughout, so the AND gate cannot output a 1.

The two circuits are two modules with the same function. The only difference is the third term.

autopilot_min.sv
// Autopilot engage logic as a minimal sum of products: whoever is in charge decides.
module autopilot_min(input logic CAR, PAR, PIC, output logic AE);
assign AE = (CAR & ~PIC) | (PAR & PIC);
endmodule
autopilot_safe.sv
// The same function with the redundant group added: CAR & PAR covers the pair of cells the other two groups miss.
module autopilot_safe(input logic CAR, PAR, PIC, output logic AE);
assign AE = (CAR & ~PIC) | (PAR & PIC) | (CAR & PAR);
endmodule

Be careful about what these two listings show. The argument that the circuit cannot glitch is about the gate network drawn above and the explicit delay model below. An assign states a Boolean function, and a synthesis tool may build the function in any way that computes it. Adding a redundant term to the source does not oblige the tool to keep the extra gate. When each of these two files was run through Yosys's generic synth command, both came out as the same single multiplexer cell, with no separate AND gate for CAR & PAR. (not machine-checked: A hand run of Yosys's generic synth command while this page was revised; it is not part of the book's checks, which stop before technology mapping.) Other tools may map the function differently, and the book did not run the tools of the lab. So do not conclude from autopilot_safe alone that a real output cannot glitch. A guarantee like that needs the tool flow to preserve the extra gate, a timing analysis of the result, or a design that samples the output safely, as a clocked design does.

A simulation with zero delays cannot show the glitch, so the book keeps a second file for each circuit, a gate-level model whose only purpose is to simulate timing. A gate primitive lists its output first, and #20, written between the gate type and the instance name, is the time the output takes to follow the inputs. Each model is checked to compute the same function as the plain module it models. That check cannot tell the two autopilot circuits apart, because they compute the same function. What makes the hazard-free model hazard-free is its extra gate, g_both, so compare the gates with the assign of the plain module by eye: one primitive per operator. The other checks are on the figures: the map of the hazard-free cover is checked to hold every pair of neighboring 1s in one group, and each simulated waveform is checked for the short pulse (present in the minimal circuit's output, absent from the hazard-free one).

autopilot_min_delay.sv
// Gate-level model of autopilot_min, for simulation only: the NOT takes 20 time units, the AND and OR gates 10 each.
module autopilot_min_delay(input logic CAR, PAR, PIC, output logic AE);
logic pic_n, via_copilot, via_pilot;
not #20 g_not(pic_n, PIC);
and #10 g_copilot(via_copilot, CAR, pic_n);
and #10 g_pilot(via_pilot, PAR, PIC);
or #10 g_engage(AE, via_copilot, via_pilot);
endmodule

The testbench holds CAR and PAR at 1 and moves PIC, so the two autopilot waveforms come from this stimulus. The hazard-free model's testbench is the same file with the other module.

autopilot_min_delay_tb.sv
// PIC falls at 100 and rises again at 160, with CAR and PAR held at 1.
module autopilot_min_delay_tb();
logic CAR, PAR, PIC, AE;
autopilot_min_delay dut(.CAR, .PAR, .PIC, .AE);
initial begin
CAR = 1'b1; PAR = 1'b1; PIC = 1'b1; #100;
PIC = 1'b0; #60;
PIC = 1'b1; #100;
$stop;
end
endmodule

Delays written with # are for simulation only. A real circuit has whatever delays its gates have, and the glitch's width depends on them.

A register copies its input only at a clock edge, and what it needs is an input that stays steady in a short window around that edge: settled shortly before the edge (the setup window) and unchanged for a short time after it (the hold window). A glitch that is over before the setup window of the capturing edge, and that does not fall inside the hold window of the previous edge, never reaches the register. Section 4.7 shows what a register does at an edge, and Chapter 6 (not yet written) will put numbers on these windows. So in a clocked design most hazards do no harm.

The dangerous signals are the ones that act at once, without waiting for an edge. An output wired to a flip-flop's clock pin could turn a glitch into a false clock edge, which is one reason this book never drives a clock from logic (Appendix C lists it among the book's house rules). An output that drives something outside the clocked design, such as a motor or a light another circuit watches, may need the redundant group, and then the design has to make sure the tools keep it.

Common pitfall

  • Calling it a hazard whenever two adjacent 1s are in different groups. The test is whether some group covers both cells, and a third group may.
  • Looking for a static-0 hazard in a sum of products, or a static-1 hazard in a product of sums. Check the 1s of the map for the first and the 0s for the second.
  • Concluding that a circuit is safe because a zero-delay simulation shows a clean output. A zero-delay simulation cannot show a glitch.
  • Treating a hazard as an error in the function. The function is right on every input; the hazard is about the moment between two right answers.
  • Treating the extra group as safe to delete, or as certain to survive. In the drawn gate network it is redundant on purpose, and simplifying it away brings the hazard back. In source code a synthesis tool may remove the redundant term or map the whole function into a multiplexer or lookup table, so the source alone does not guarantee a hazard-free output.
  • Assuming a hazard-free cover also protects against two inputs changing at nearly the same time. The test is about one input changing at a time.
Take the quiz (5 questions)

For the autopilot function, which product term is the group that holds the cells where CAR, PAR and PIC are 1, 1, 0 and 1, 1, 1?

Which of these can be added to the minimal autopilot circuit as a third term without changing the function?

How many gates does the hazard-free autopilot circuit in Figure 3.8.5 use, counting the NOT gate?

When does a two-level sum-of-products circuit have a static-1 hazard for a single input change?

A product-of-sums circuit should hold its output at 0 while one input changes, but the output spikes to 1 for a moment. What is this?

Exercise 3.8.1

The function AB+CDAB + CD is built as two AND gates and an OR gate. The two groups on its map share one cell. Does the circuit have a static-1 hazard for any single-input change?

Karnaugh map of F: columns AB, rows CD0010001011110010ABCD0001111000011110

F = AB+CDAB + CD

  • ABABcolumn of four: column 11 (4 cells)
  • CDCDrow of four: row 11 (4 cells)
Karnaugh map of F: columns AB, rows CD; cell values are 0, 1 or X for don't care
AB=00AB=01AB=11AB=10
CD=000010
CD=010010
CD=111111
CD=100010

Groups drawn:

  1. A and B: column of four in column AB=11; 4 cells.
  2. C and D: row of four in row CD=11; 4 cells.

Description: A four-variable Karnaugh map with two overlapping groups of four cells.

Figure 3.8.10. A function of four variables with the two groups of the cover drawn.
Hint
Take a 1 that is in only one of the groups. If you change one input and land on another 1, is that new cell in the same group?
Solution

No. Take a cell of the first group that is not in the second. C&D is false there, because the cell is not in the second group. Changing C or D moves to another cell of the first group. Changing A or B makes A&B false, and C&D is still false, so the new cell is a 0. So every neighbor of this cell that is a 1 is in the same group as the cell, and a gate that holds the pair covers both. The same argument works for the second group, and the one cell the groups share has both gates on. No pair of adjacent 1s is left without a group, so the circuit has no static-1 hazard. Two groups overlapping does not create a hazard; an uncovered pair of neighbors does.

Tags: Warm-upHazardsKarnaugh maps

Exercise 3.8.2

The ring function of Exercise 3.6.5 has two minimal covers. Use the cover in the figure. Which single-input changes can produce a static-1 hazard, and what is the smallest cover that removes all of them?

Karnaugh map of F: columns AB, rows C10111110ABC0001111001

F = A‾ B‾+BC+AC‾\overline{A}\,\overline{B} + BC + A\overline{C}

  • A‾ B‾\overline{A}\,\overline{B}vertical pair: column 00 (2 cells)
  • BCBChorizontal pair: row 1, columns 01 and 11 (2 cells)
  • AC‾A\overline{C}horizontal pair: row 0, columns 11 and 10 (2 cells)
Karnaugh map of F: columns AB, rows C; cell values are 0, 1 or X for don't care
AB=00AB=01AB=11AB=10
C=01011
C=11110

Groups drawn:

  1. not A and not B: vertical pair in column AB=00; 2 cells.
  2. B and C: horizontal pair in row C=1, columns AB=01 and 11; 2 cells.
  3. A and not C: horizontal pair in row C=0, columns AB=11 and 10; 2 cells.

Description: A three-variable Karnaugh map with six 1s and three groups of two cells each.

Figure 3.8.11. The ring function with one of its minimal covers.
Hint
List the pairs of neighbors that are both 1. Cross off every pair that is inside one drawn group. Each pair that is left needs a group.
Solution

Every 1 has two neighbors that are 1, so the ring has six neighboring pairs, one for each step around the ring. The three drawn groups hold three of the pairs. The three pairs left over are the ones that no drawn group holds. The horizontal pair wrapping around the left and right edges in row C=0, columns AB=10 and 00 holds the first of them, with A changing. The horizontal pair in row C=1, columns AB=00 and 01 holds the second, with B changing. The vertical pair in column AB=11 holds the third, with C changing. Adding all three gives a cover of all six pairs.

Karnaugh map of F: columns AB, rows C10111110ABC0001111001

F = A‾ B‾+BC+AC‾+B‾ C‾+A‾C+AB\overline{A}\,\overline{B} + BC + A\overline{C} + \overline{B}\,\overline{C} + \overline{A}C + AB

Hazard-free for single input changes: every pair of adjacent 1 cells is held by one drawn group.

  • A‾ B‾\overline{A}\,\overline{B}vertical pair: column 00 (2 cells)
  • BCBChorizontal pair: row 1, columns 01 and 11 (2 cells)
  • AC‾A\overline{C}horizontal pair: row 0, columns 11 and 10 (2 cells)
  • B‾ C‾\overline{B}\,\overline{C}horizontal pair, wraps left and right: row 0, columns 10 and 00 (2 cells)
  • A‾C\overline{A}Chorizontal pair: row 1, columns 00 and 01 (2 cells)
  • ABABvertical pair: column 11 (2 cells)
Karnaugh map of F: columns AB, rows C; cell values are 0, 1 or X for don't care
AB=00AB=01AB=11AB=10
C=01011
C=11110

Groups drawn:

  1. not A and not B: vertical pair in column AB=00; 2 cells.
  2. B and C: horizontal pair in row C=1, columns AB=01 and 11; 2 cells.
  3. A and not C: horizontal pair in row C=0, columns AB=11 and 10; 2 cells.
  4. not B and not C: horizontal pair wrapping around the left and right edges in row C=0, columns AB=10 and 00; 2 cells.
  5. not A and C: horizontal pair in row C=1, columns AB=00 and 01; 2 cells.
  6. A and B: vertical pair in column AB=11; 2 cells.

Description: The ring map with six groups of two cells, one for every pair of neighboring 1s.

Figure 3.8.12. All six pairs of the ring as groups.

The three added terms are exactly the terms of the other minimal cover in Exercise 3.6.5. Together the two minimal covers form the hazard-free cover, with six terms where the minimum has three. No group of four fits on the ring, so each neighboring pair can be held only by a group that is that pair. Six pairs need six terms, so this cover is the smallest hazard-free one.

Tags: StandardHazardsKarnaugh maps

Exercise 3.8.3

Draw the map of AB‾C+BDA\overline{B}C + BD and find the single-input change that can cause a static-1 hazard. Give a group to add, and the new sum of products.

Hint
Mark the 1s of each product, then look for two neighbors that are 1 but are held by different products.
Solution

The first product is 1 in the two cells where A is 1, B is 0 and C is 1. The second is 1 in the four cells where B and D are 1. The cell where A, B, C and D are 1, 0, 1, 1 belongs to the first product, and its neighbor where A, B, C and D are 1, 1, 1, 1 belongs to the second. They differ only in B, and no group of the cover holds both. That change is the hazard. The group that holds the pair has A, C and D fixed at 1 and B changing, so its term is ACDACD.

Karnaugh map of F: columns AB, rows CD0000011001110001ABCD0001111000011110

F = AB‾C+BD+ACDA\overline{B}C + BD + ACD

Hazard-free for single input changes: every pair of adjacent 1 cells is held by one drawn group.

  • AB‾CA\overline{B}Cvertical pair: rows 11 and 10, column 10 (2 cells)
  • BDBD2-by-2 square: rows 01 and 11, columns 01 and 11
  • ACDACDhorizontal pair: row 11, columns 11 and 10 (2 cells)
Karnaugh map of F: columns AB, rows CD; cell values are 0, 1 or X for don't care
AB=00AB=01AB=11AB=10
CD=000000
CD=010110
CD=110111
CD=100001

Groups drawn:

  1. A and not B and C: vertical pair in rows CD=11 and 10, column AB=10; 2 cells.
  2. B and D: 2-by-2 square in rows CD=01 and 11, columns AB=01 and 11; 4 cells.
  3. A and C and D: horizontal pair in row CD=11, columns AB=11 and 10; 2 cells.

Description: A four-variable Karnaugh map with a pair, a square and a second pair that overlaps both.

Figure 3.8.13. The cover with the added group in which B changes.

The new sum of products is AB‾C+BD+ACDA\overline{B}C + BD + ACD, and AB‾C+BD=AB‾C+BD+ACDA\overline{B}C + BD = A\overline{B}C + BD + ACD confirms it is the same function. It is no longer minimal, because it has three terms where the minimum has two.

Tags: StandardHazardsKarnaugh maps

Exercise 3.8.4

A 2-to-1 multiplexer, with the data inputs numbered by the select as in Definition 2.7.2, is built from gates as S‾D0+SD1\overline{S}D_{0} + SD_{1}. The NOT gate and both AND gates take 20 time units, and the OR gate takes 10. D0 and D1 stay at 1. The select S falls and, later, rises again.

  1. Draw the lanes dut.s_n (the NOT output), dut.take_d0 and dut.take_d1 (the outputs of the two AND gates) and Y.
  2. Does Y have a glitch? In which direction of S, and what kind of hazard is it?
  3. Say which group to add to the sum of products to remove the hazard.
Waveform ch03/mux-gates-trace: D0, D1, S, dut.s_n, dut.take_d0, dut.take_d1, YD0D1Sdut.s_ndut.take_d0dut.take_d1Y90100110120130140150160170180190200time (ps)Waveform ch03/mux-gates-trace: D0, D1, S, dut.s_n, dut.take_d0, dut.take_d1, YD0D1Sdut.s_ndut.take_d0dut.take_d1Y90100110120130140150160170180190200time (ps)Waveform ch03/mux-gates-trace: D0, D1, S, dut.s_n, dut.take_d0, dut.take_d1, YD0D1Sdut.s_ndut.take_d0dut.take_d1Y90110130150170190time (ps)Waveform ch03/mux-gates-trace: D0, D1, S, dut.s_n, dut.take_d0, dut.take_d1, YD0D1Sdut.s_ndut.take_d0dut.take_d1Y90110130150170190time (ps)Waveform ch03/mux-gates-trace: D0, D1, S, dut.s_n, dut.take_d0, dut.take_d1, YD0D1Sdut.s_ndut.take_d0dut.take_d1Y90110130150170190time (ps)

Time in ps; one column is 10 ps.

Timing diagram from simulation, ch03/mux-gates-trace: time in ps from 90 to 210, 12 columns of 10 ps.

D0: 1 at 90, no changes.

D1: 1 at 90, no changes.

S: 1 at 90, then 0 at 100, 1 at 160.

Empty lanes for the reader to complete: dut.s_n, dut.take_d0, dut.take_d1, Y.

Description: A timing diagram of D0, D1 and S, with the lanes for s_n, take_d0, take_d1 and Y left empty. D0 and D1 stay at 1; S falls once and rises later.

Figure 3.8.14. The question: the inputs of the multiplexer.
Hint
Each gate output changes its delay after the input that causes the change. Start with s_n and take_d1, then work forward to the OR gate. Y changes only when both OR inputs are 0 or when one becomes 1.
Solution

When S falls, take_d1 falls one AND delay later, and s_n rises one NOT delay later. The gate for D0 sees s_n, so take_d0 rises one AND delay after that, which is 20 more than take_d1's fall. Both AND outputs are 0 between the two changes. The OR gate shows it one OR delay later: Y falls one OR delay after take_d1 falls, and rises one OR delay after take_d0 rises. When S rises again, the changes happen in the opposite order: take_d1 rises and s_n falls at the same time, and take_d0 falls one AND delay after that, so both terms are 1 for a while and Y stays at 1.

Waveform ch03/mux-gates-trace: D0, D1, S, dut.s_n, dut.take_d0, dut.take_d1, YD0D1Sdut.s_ndut.take_d0dut.take_d1Y90100110120130140150160170180190200time (ps)Waveform ch03/mux-gates-trace: D0, D1, S, dut.s_n, dut.take_d0, dut.take_d1, YD0D1Sdut.s_ndut.take_d0dut.take_d1Y90100110120130140150160170180190200time (ps)Waveform ch03/mux-gates-trace: D0, D1, S, dut.s_n, dut.take_d0, dut.take_d1, YD0D1Sdut.s_ndut.take_d0dut.take_d1Y90110130150170190time (ps)Waveform ch03/mux-gates-trace: D0, D1, S, dut.s_n, dut.take_d0, dut.take_d1, YD0D1Sdut.s_ndut.take_d0dut.take_d1Y90110130150170190time (ps)Waveform ch03/mux-gates-trace: D0, D1, S, dut.s_n, dut.take_d0, dut.take_d1, YD0D1Sdut.s_ndut.take_d0dut.take_d1Y90110130150170190time (ps)

Time in ps; one column is 10 ps.

Timing diagram from simulation, ch03/mux-gates-trace: time in ps from 90 to 210, 12 columns of 10 ps.

D0: 1 at 90, no changes.

D1: 1 at 90, no changes.

S: 1 at 90, then 0 at 100, 1 at 160.

dut.s_n: 0 at 90, then 1 at 120, 0 at 180.

dut.take_d0: 0 at 90, then 1 at 140, 0 at 200.

dut.take_d1: 1 at 90, then 0 at 120, 1 at 180.

Y: 1 at 90, then 0 at 130, 1 at 150.

Description: The full timing diagram. Y dips to 0 for two columns after S falls and stays at 1 after S rises.

Figure 3.8.15. The answer: every signal, from the same simulation.

Y dips for two columns after S falls. The output should stay at 1 before and after, so this is a static-1 hazard, and it appears when S falls with these delays. The hazard is the pair of neighbors where D0 and D1 are 1 and S changes. The group that holds it is D0D1D_{0}D_{1}, and S‾D0+SD1=S‾D0+SD1+D0D1\overline{S}D_{0} + SD_{1} = \overline{S}D_{0} + SD_{1} + D_{0}D_{1} confirms that adding it does not change the multiplexer.

Tags: ChallengeHazardsWaveforms

Exercise 3.8.5

The product of sums (A‾+B)⋅(A+C‾)(\overline{A} + B) \cdot (A + \overline{C}) is built as two OR gates, with a NOT gate on each input that needs one, and an AND gate. Find a single-input change that can cause a static-0 hazard, and give the sum to add.

Hint
Draw the map of the complement and find two neighbors that are 1 there, but are held by different groups.
Solution

The complement is (A‾+B)⋅(A+C‾)‾\overline{(\overline{A} + B) \cdot (A + \overline{C})}. Its two groups are the vertical pair in column AB=10, which corresponds to the sum A‾+B\overline{A} + B, and the horizontal pair in row C=1, columns AB=00 and 01, which corresponds to the sum A+C‾A + \overline{C}. The cell where A, B and C are 0, 0, 1 and the cell where they are 1, 0, 1 are neighbors, and both are zeros of H. The first is in one group and the second in the other, and no group holds both. The group that does is the horizontal pair wrapping around the left and right edges in row C=1, columns AB=10 and 00, with A changing, and its sum is B+C‾B + \overline{C}.

Karnaugh map of Hn: columns AB, rows C00011101ABC0001111001

Hn = AB‾+A‾C+B‾CA\overline{B} + \overline{A}C + \overline{B}C

Hazard-free for single input changes: every pair of adjacent 1 cells is held by one drawn group.

  • AB‾A\overline{B}vertical pair: column 10 (2 cells)
  • A‾C\overline{A}Chorizontal pair: row 1, columns 00 and 01 (2 cells)
  • B‾C\overline{B}Chorizontal pair, wraps left and right: row 1, columns 10 and 00 (2 cells)
Karnaugh map of Hn: columns AB, rows C; cell values are 0, 1 or X for don't care
AB=00AB=01AB=11AB=10
C=00001
C=11101

Groups drawn:

  1. A and not B: vertical pair in column AB=10; 2 cells.
  2. not A and C: horizontal pair in row C=1, columns AB=00 and 01; 2 cells.
  3. not B and C: horizontal pair wrapping around the left and right edges in row C=1, columns AB=10 and 00; 2 cells.

Description: A three-variable Karnaugh map with three groups of two cells.

Figure 3.8.16. The complement's map with the added group in which A changes.

The new product of sums is (A‾+B)⋅(A+C‾)⋅(B+C‾)(\overline{A} + B) \cdot (A + \overline{C}) \cdot (B + \overline{C}), and (A‾+B)⋅(A+C‾)(\overline{A} + B) \cdot (A + \overline{C}) =(A‾+B)⋅(A+C‾)⋅(B+C‾)= (\overline{A} + B) \cdot (A + \overline{C}) \cdot (B + \overline{C}) confirms it is the same function.

Tags: ChallengeHazardsKarnaugh maps