Consider a state machine whose entire state is kept in a collection of edge-triggered D flip-flops. The outputs of these are fed into a combinatorial network which fully determines the next state, and is fed back into the flip-flops' inputs. On every pulse of the clock, the FSM transition states.
However, I am unsure about how to deal with races: on the positive edge of the clock, the flip-flops will propagate their inputs to their internal states (and outputs). Immediately, the outputs (through the combinatorial network) will change the flip-flops' inputs again. How is it guaranteed that the inputs are stable for long enough after the clock edge for the flip-flops to switch effectively?
I can think of two possible workarounds:
Cascade two sets of flip-flops; this keeps the inputs stable, but would take two clock cycles to transition states.
Use master-slave flip-flops. I am not sure whether this completely fixes the race, though: if the clock inverter (gating the "slave" flip flop) switches quickly (before the "master" flip flop" turns off), it could still result in unstable inputs.
How is this usually solved?