Why do we not care about intermediate values inbetween rises of the clock with a D-type flip-flop?

I teach D-type flip-flops as part of A level computer science in a very basic way. A student asked me today why we don't care about intermediate values inbetween rises of the clock with a D-type flip-flop.

I know we use these circuits in processor caches and registers, but couldn't think of a scenario which would generate an intermediate value which should not be stored. Can anyone help?

• Tell me in your own words, Tortoise: What does a D flip-flop do? Commented Oct 13, 2022 at 19:44
• It stores the value of a bit. Whatever the input value is on the rising edge of the clock is what's stored. Commented Oct 13, 2022 at 20:35
• Right, and anything else that happens before or after the clock edge rises, it doesn't care about. For a single FF this is pretty useless, but chain several of them together (Justme's answer) and it becomes an important "feature." Commented Oct 13, 2022 at 21:20
• @Tortoise What about the input value when it's not the rising edge of the clock? Does that do anything? Commented Oct 14, 2022 at 11:20
• So if the input value is on the rising edge of the clock is what's stored as long as setup and hold times on D are met for the rising edge. No rising edge on clock means the input value on D can be anything. Commented Oct 14, 2022 at 17:13

The question asks for examples of where a rising-edge triggered D-type Flip-Flop (DFF) ignores changes on its D input between CLK rising edges.

That function is a fundamental of the operation of synchronous logic circuits and a building block of larger such circuits.

Consider the example synchronous logic circuit. On a CLK rise, if DFF1 and DFF2 take on new values then the OR gate output will produce intermediate and transient outputs before settling.

DFF3 ignores these intermediate values and only latches the settled OR output on the next CLK rise.

So the examples of where this is used is: every synchronous logic circuit with combinatorial logic placed between DFFs. That's the majority of the digital circuits actually produced and around us.

simulate this circuit – Schematic created using CircuitLab

Why Doesn’t The Flip-Flop Care About Intermediate Values?

Short answer: that’s how clocked flip-flops are designed to work. They’re edge-triggered, on the clock. This differentiates them from the D latch, which is level sensitive on its enable.

Since it’s edge-triggered, a D flip-flop only cares about the data input state in the time period near where the clock input toggles.

This time period where the D flop ‘cares’ about its D input is the window of time between two key markers:

• T(setup) min: minimum input setup before clock
• T(hold) min: minimum input hold time after clock

From here

I’ll call this region shown between the setup and hold markers the data-valid window. If the flip-flop D input is held stable during the data-valid window, the flop will faithfully transfer that input state to its Q output at the next clock edge. The rest of the time outside the data-valid window, the flip-flop doesn’t care about its input.

Indeed, outside of the data-valid window, the D input can change state many times without affecting the flop output, so long as the D input reaches a stable state before the next data-valid window.

Nevertheless, this ‘don’t care’ time is important: it’s where a lot of business gets done.

This 'business' is often represented as a register-to-register combinatorial cloud, in diagrams like this:

From here

Follow that red-arrow path. The sending flop launches its data signal, which propagates through the asynchronous (combinatorial) logic in the path to compute the next state, where it’s finally captured by the receiving flop.

Let's dig into your actual question now.

’Why do we not care about intermediate values in between rises of the clock?’

Turns out, as digital designers we do care about what’s going on between clock edges, even if the receiving flip-flop doesn’t.

Take another look at that second diagram. What’s in that comb_delay cloud? Could be anything - an ALU, a multiplier, a RAM, a multiplexer, some gates or maybe just a wire. In other words, it's not just a delay. This combinatorial cloud defines the very purpose of the machine. It’s where the logic lives.

Regardless of what’s in it, the combinatorial path will have some delay, taking a finite time to propagate and settle to its final value in response to its input state.

Depending on the logic layers and internal delays present in the combinatorial path, the D input could toggle (glitch) multiple times before arriving at a final state. However, in a flop-to-flop machine, we don’t care about these intermediate values or glitches, only the final propagated-and-settled value so long as the receiving flop timing is met.

Just because we ‘don’t care’ at the flip flop input outside of its data-valid window, we still really care about this combinatorial cloud delay. All this propagating and logic-computing work must get finished before the next data-valid window arrives, where we dutifully capture it at the next clock edge.

This delay has a major impact on machine performance. The combinatorial delay, plus flop setup time determine the minimum clock cycle time we can achieve.

In sum, in a flop-to-flop path, we do care about intermediate values, only about their time to propagate and settle to a final value, and not about values that might occur along the way.

Are there cases when do we care about intermediate values? Yes, there’s a couple.

• If we’re decoding a signal asynchronously from a group of signals that has more than one input changing at a time, or have logic with unequal skew.

If the signals being decoded have unequal arrival times or unequal logic paths, the decoded output can glitch.

This comes up often with ripple counters, which by their nature have skew between their outputs: values decoded from their outputs will glitch until all the ‘rippling’ is completed and the logic settles. (Synchronous counters can have the same issue; I’ll touch on this below when I discuss Moore machines.)

Non-clocked interfaces like static RAM suffer this issue, and so include strobes (e.g., RD#, WR#) to qualify the address and data. The strobes cover over (mask) the decode and settling time so that the resulting device decode is glitch-free.

This issue also comes up with FIFO full/empty signals: bit-to-bit skew on the address counters can cause the full/empty logic to glitch. FIFOs work around the problem by using Gray codes to compute full/empty, as only one bit changes at a time.

• If we're building a Mealy state machine.

Mealy state machines have an asynchronous path between the clocked output state and possibly also external inputs. This introduces a hazard: if there is skew in these signals or their decoding logic, the decoded outputs can glitch. This is (somewhat) differentiated from a Moore state machine, which has registered outputs and thus would ignore glitches.

From here

(Extra credit: Do you also see a problem with the Moore machine? What if there is timing skew to and within the 'decode' logic?)

Why Bother With Flops At All?

The clocked flip-flop allows clock-coordinated changes of state. In clocked systems, data can be handed from one flop to the next in an orderly, synchronous fashion, clock by clock. This allows us to build systems that break up combinatorial logic into smaller steps with well-controlled delays. (Not to mention that D registers can hold state, create fast memories as well as other uses.)

The drawbacks to a clocked system? Increased latency; any unused timing slack is ‘wasted’; increased complexity; increased power.

For these reasons, asynchronous computing continues to be an area of academic study. As we move into a future of new computational structures like quantum computing and neuromorphic models among others, async could become the new paradigm that replaces clocked designs.

So far we’ve talked about setup, hold, clock-to-output and combinatioral delay - four key timing analysis parameters. You might wonder what happens if, because of a timing violation, the flip-flop’s data-valid window isn’t met? Well, a couple of Bad Things. The flop could get state on the wrong cycle. If you're unlucky enough, it could even enter a metastable state where the output isn’t resolved to one logic level or another. Unpredictable behavior can result.

Failing to meet the data-valid window is of great concern. Real designs aren’t just flip-flops connected to each other. They also have additional delays / skews on data and clock, which can work for you or against you timing-wise. For example, logic inserted in the data path helps hold time but eats into setup time; while logic inserted on the clock (e.g., gated clock for power saving) eats into hold time but helps with setup.

One more thing. Clocked flip-flops also have an output parameter for clock-to-output delay (T(cq)). In a direct flop-to-flop connection, this delay needs to be at least as long as the receiving flop hold time, but not so long as to cause setup time to be missed.

More broadly, a good chunk of the work in digital design, at both the chip and system level, is carefully balancing delays on clock and data, as well as accounting for all other influences on timing (process, voltage, temperature, routing) to assure that all flip-flop data-valid windows are met. This discipline is called timing closure or AC sign-off, a demanding but essential task to assure a reliable system that will work under all target conditions.

Obviously one application is a bus with multiple flip-flops.

For example when implementing registers and cache like you mentioned.

You want all the other flip-flops to ignore all activity on the data bus while you are updating the specific flip-flop you want to address on the data bus.