Both your designs are asynchronous state machines that have absolutely no guarantee to work.
The main problem is the following lines:
Code:
if (clk_gate='1' and clk_edge='1') then
clk_edge := '0';
As soon as the "if" is true, it will become false again. This means that the rest of the statements in that "if" clause are controlled
by a very short pulse. You have no control over the length and there is no guarantee that it is detected by all logic.
This is why your second code example failed, but your first example can fail in the same way. You have no guarantee.
You should avoid asynchronous state machines like this. They can work but you will get no help from the tools,
so you must know exactly what you are doing.
Because of the high frequency of "fin", you probably need two clock domains in the design, "fin" and the system clock.
To make sure that the real circuit behaves as the simulation, follow some rules:
1. No asynchronous state machines unless you can prove they are safe.
2. All clocked processes based on the standard template
3. Syncronize all signals that enter a clock domain.
The frequency counter is a non-trivial task, especially if "fin" is allowed to go down to 0 Hz.
Why the "high word" / "low word"? With your code, the maximum frequency will be the same for one long counter.
Also remember that "unsigned" will wrap to zero automatically.