Help with designing falling edge detector using a state machine
Well since your circuit does perform its intended function, I'd say by definition you didn't do anything "wrong". But I think solving this problem with a state machine is unnecessarily complex, and a more intuitive approach does yield the circuit shown in your link.

Rather than a "state machine" approach I'd say it's far better to use a "plain English" approach -- clearly define what your circuit needs to do, then implement that description in circuitry.


A Falling Edge Detector needs to output a '1' pulse whenever the input makes a high-to-low transition.
To put this in more logic-friendly terms, a Falling Edge Detector needs to output a '1' whenever the current value of the input is low, and the previous value of the input is high.


If you look at the Cypress circuit, that's exactly what it's saying: there is an AND gate which fires when the present value is low and the previous value is high.

We can also translate your circuit into "plain English" and see that the output is '1' when the present value is low and the previous-value-of-the-inverted-input is also low. With a bit of reasoning you can see that this is the same thing, just expressed in a more complex fashion.

Style Points: having any signal, input or output, last for less than one full clock cycle is a Cardinal Sin of good synchronous logic design and should be avoided at all costs. Having these types of asynchronous signals means that you cannot guarantee proper setup/hold times for the downstream logic, and so you can encounter erratic behavior that is practically impossible to track down and fix. I'm really surprised that Cypress let this into a document that they published.

EDIT

@Eran asked if would be okay to run the async signal into the FF enable pin, as he's seen on multiple sites. This still violates the principles of good synchronous logic design, and yes I would go so far as to say that all those sites are wrong.

When designing synchronous digital logic circuits (really anything involving clocked flip-flops) it is best to be VERY religious about having all signals being properly clocked to avoid having to deal with intermittent, weird failures. If you're dealing with signals from the outside world which aren't synchronized to your clock, then run them through a synchronizer (typically two FFs in series) to line them up to your clock. This will minimize the chance of metastability, but it can never be eliminated.

A nice overview is here: https://web.stanford.edu/class/ee183/handouts/synchronization_pres.pdf. Direct quote from that document: "Synchronization failure is deadly and difficult to debug." So yes it's best to be methodical from the outset and avoid the need to debug it.

For "hobbyist" designs people probably just choose to live with these and hit the RESET button occasionally. For professional, robust designs good synchronous logic design principles are a must.