A simulation shows that your code actually does generate divided clocks, but the large integers used in the division gives periods up to 500 ms when dividing a 100 MHz clock, so you may not have waited long enough :-)
You can see the simulation below.
You can indeed store process state in process variables, since that state is retained between suspensions of the process. Note that the process is not invoked between runs, like a ordinary software function, but simply suspended at the end (when having a sensitivity list), and execution is then resumed at an event at one of the signals in the sensitivity list.
Some comments to the code:
The assign to
clk*
should go inside theif rising_edge(clk)
, since you probably want these outputs to be from flip-flops.Consider using the state in
clk*
instead of thed
,f
, andh
variables, since it is almost redundant.Consider making the counters with signal based on
std_logic_vector
, instead of the internal integer variables, since debugging is typically easier when using signals that can be shown easily in a waveform, and you have better control over the implementation. For example when debugging, you would have seen that the counters actually incremented, and thus may have understood that the divider works, but the resulting clock just have a long period.