13.4 Race Conditions: When Signal Paths Disagree
Explain hardware race conditions, distinguish them from software races, and describe the race-around problem in a level-triggered JK flip-flop and its master-slave fix.
A race condition, in digital hardware, occurs when a circuit's final state depends on the relative arrival order of two or more signal changes that happen nearly simultaneously — if the outcome differs depending on which change 'wins the race' to take effect first, the circuit's behavior is ambiguous or non-deterministic. This lesson covers both general hardware/simulation races and one specific, classic instance worth knowing by name: the race-around condition in a level-triggered JK flip-flop, which is exactly the reason the master-slave flip-flop architecture was invented.
Core concept: multiple simultaneous changes, ambiguous outcome
A hardware race arises whenever two or more inputs to a circuit change at nearly the same instant and the circuit's output depends on which one's effect propagates through and settles first. In feedback circuits especially (latches, asynchronous state machines), a race can mean the circuit's next state is genuinely unpredictable — determined by small, uncontrolled variations in individual gate delays rather than by the intended logical design. This is different from a hazard (Module 13.5), where a *single* input transition causes a momentary glitch due to unequal path delays even though the final steady-state output is well-defined; a race is about *multiple* simultaneous or near-simultaneous changes producing genuinely ambiguous final behavior.
Simulation races are a related but distinct concept in HDL simulation: when a simulator processes multiple events scheduled at exactly the same simulation time step, the order in which it evaluates them can (for certain coding styles, especially mixing blocking and non-blocking assignments carelessly) affect the simulated result even though real hardware would behave deterministically (or would itself have the same physical race) — a well-known class of simulation-vs-synthesis mismatch bug that careful RTL coding guidelines exist specifically to avoid.
The classic case: race-around in a level-triggered JK flip-flop
A JK flip-flop's defining feature is that J=K=1 causes it to toggle. In a purely level-triggered (as opposed to edge-triggered) implementation, the flip-flop responds to its inputs for the *entire duration* the clock/enable level is active, not just at a single edge instant. If J and K are both held at 1 throughout an active clock pulse, and the clock pulse's active-level duration (Tp) is longer than the flip-flop's own feedback propagation delay (tpd) — the time for the output to travel back around through the JK logic and affect the next toggle — the flip-flop will toggle multiple times within that single clock pulse, roughly Tp/tpd times, landing on an output value that depends unpredictably on the exact ratio between pulse width and propagation delay rather than on any clean, intended single-toggle behavior. This is the race-around condition, and it is a genuine hardware race: the flip-flop's own output feeds back into its own next-state logic while the clock is still active, racing against itself.
The standard, historically important fix is the master-slave flip-flop architecture (covered fully in Module 8), which splits the flip-flop into two stages — a master latch that samples the inputs while the clock is in one phase, and a slave latch that only updates the visible output during the *other* clock phase, once the master's inputs are already locked out. Because the master and slave are never transparent (able to be influenced by their own feedback) at the same time, the output can only change once per clock cycle no matter how long the active clock level lasts, structurally eliminating the race-around problem. Fully edge-triggered flip-flop designs (used throughout modern synchronous design) sidestep the issue entirely by responding only to the clock edge's *instant*, never to a sustained level, so there's no window during which feedback can race with itself.
Race-around condition, symbolically
Level-triggered JK, J = K = 1, clock active-level duration = Tp
Feedback propagation delay = tpd
If Tp > tpd:
number of toggles during one active pulse ≈ Tp / tpd
final output state becomes unpredictable / undesired
Fix: master-slave architecture
master samples while clock = 1 (or 0, depending on design)
slave updates only while clock = other phase
→ output changes at most once per clock cycle, regardless of TpCode Examples
With a 50 ns active pulse and a 10 ns feedback loop delay, the flip-flop has time to toggle about five times before the clock level deactivates — an odd or even number of these unintended extra toggles determines whether the final output matches or is inverted relative to what a single clean toggle would have produced, and that number is sensitive to exact delay variations the designer doesn't fully control.
Toggles per pulse ≈ Tp/tpd = 5 — far more than the single intended toggle, and the final state is effectively unpredictable.
Common mistake: Assuming a level-triggered JK flip-flop always toggles exactly once per active clock pulse when J=K=1 — it only does so if the pulse is short relative to the feedback delay, or if a master-slave architecture is used.
Clock pulse width Tp = 50 ns
Feedback propagation delay tpd = 10 ns
J = K = 1 held throughout the pulse
Approx. toggles during the pulse ≈ Tp / tpd = 50 / 10 = 5
→ The output toggles roughly 5 times within one active clock pulse;
its final resting value is effectively determined by unpredictable
timing variation, not by clean, intended single-cycle toggle logic.Important Rules
A race condition occurs when a circuit's outcome depends on the relative arrival order of near-simultaneous signal changes.
Race-around is specific to level-triggered JK flip-flops with J=K=1 held for an active-level duration longer than the feedback propagation delay.
Master-slave flip-flop architecture eliminates race-around by never letting the master and slave be simultaneously transparent.
Fully edge-triggered flip-flops avoid race-around entirely by responding only to the clock edge instant, not to a sustained active level.
Why master-slave flip-flops mattered historically
Classic parts like the 74LS76 dual JK flip-flop used a master-slave design specifically to make level-triggered JK behavior usable in real synchronous systems without race-around risk. Modern standard-cell and FPGA flip-flops are essentially all fully edge-triggered D-type elements, which sidesteps the entire race-around discussion by construction — but the historical master-slave solution remains a standard topic precisely because it's the clearest illustration of *why* edge-triggering, not just level-sensitivity with a fast enough loop, became the default choice for synchronous digital design.
Confusing a hardware race-around condition with a software race condition (e.g., two threads incrementing a shared variable without synchronization).
Recognize race-around as a specific hardware/timing phenomenon in level-triggered feedback circuits, distinct from software concurrency races even though both share the word 'race.'
This is the spec's own explicit tricky-problem warning: a software race condition is about the *order of operations* on shared memory/state across concurrent execution threads, resolved with locks/atomics — an entirely different mechanism from race-around, which is about a physical feedback loop's propagation delay relative to a clock pulse's active-level duration in a specific flip-flop topology.
Tricky problem (from the spec): why must a hardware race-around condition never be confused with a software race condition? A. They are actually the same phenomenon, just described with different vocabulary in different fields B. Race-around is a specific hardware timing phenomenon in level-triggered JK feedback loops (pulse width vs. propagation delay), while a software race condition concerns the order of concurrent operations on shared state — different mechanisms, different fixes (master-slave/edge-triggering vs. locks/atomics) C. Software race conditions only happen in single-threaded programs D. Race-around only happens in software simulators, never in real hardware
B. Race-around is a specific hardware timing phenomenon in level-triggered JK feedback loops (pulse width vs. propagation delay), while a software race condition concerns the order of concurrent operations on shared state — different mechanisms, different fixes (master-slave/edge-triggering vs. locks/atomics) — Despite the shared word 'race,' these are unrelated mechanisms: race-around is a physical consequence of a level-sensitive feedback loop's propagation delay being shorter than the active clock pulse; a software race condition is about the nondeterministic interleaving of concurrent memory accesses. Conflating them leads to reaching for the wrong fix (e.g., trying to add a 'lock' to a flip-flop, or trying to redesign silicon to fix a multithreading bug).
Interview question: why does a master-slave JK flip-flop eliminate race-around even if J=K=1 is held for the entire active clock level? A. Because the master-slave design ignores J and K entirely B. Because the master and slave stages are never simultaneously transparent — the master captures inputs during one clock phase while isolated from the output, and the slave only updates the visible output during the other phase, so the output can change at most once per full clock cycle regardless of how long the active level lasts C. Because master-slave flip-flops run at twice the clock frequency D. Because the slave stage has no feedback path at all
B. Because the master and slave stages are never simultaneously transparent — the master captures inputs during one clock phase while isolated from the output, and the slave only updates the visible output during the other phase, so the output can change at most once per full clock cycle regardless of how long the active level lasts — Race-around requires the flip-flop's own output to feed back and influence a further toggle *while the triggering condition is still active*. By construction, a master-slave flip-flop's output (from the slave) never changes while the master is actively sampling J/K, and the master is locked out from re-sampling while the slave is updating — breaking the feedback loop that race-around depends on, no matter how long the clock stays at its active level.
A level-triggered JK flip-flop has a feedback propagation delay of 8 ns. For what maximum active-clock-pulse width Tp can the designer be confident the flip-flop toggles exactly once (avoiding race-around)?
To guarantee at most one toggle, the active pulse width must be shorter than the feedback propagation delay: Tp < tpd = 8 ns. Any pulse width at or above 8 ns risks the output feeding back and re-triggering a second toggle before the pulse ends, so a safe design keeps Tp comfortably below 8 ns — though in practice, designers avoid this fragile timing-dependent approach altogether and simply use a master-slave or edge-triggered flip-flop rather than trying to keep pulse width under a delay-dependent threshold.
Race-around requires Tp > tpd; think about what condition guarantees at most one toggle.