Enable clock for a state machine

clockstate-machinesvhdl

I have 100Mhz system clock and I would like to have a 200Hz Enable signal for enabling the state machine. I need a clock divider for this process and thought about this :

clkdiv : process (clk)
begin
    if (clk'event and clk = '1') then     -- rising clock edge
        -- default value
        EN <= '0';

        clkcntr <= clkcntr - 1;
        if clkcntr = 0 then
            clkcntr   <= X"7A120"; -- 500000 decimal value
            EN <= '1';
        end if;

    end if;
end process clkdiv;

I have seen other implementations on the internet they always start first dividing with 100Mhz to 2. In my case I should decrement 250000 time to match this, is this because clk is 1-0-1-0-1-0-1-0, since we are interested on the rising edge we should also consider the falling edge times? I would be glad if someone can demonstate a proper clock divider.
Then when I am done I would like to go into the state machine with an if condition

if EN = '1' then

 go into the state machine

end if;

In the end I would like the duration of my output signal from the FSM be 200Hz long, would this be correct? Are there other ways for implementing this?

Best Answer

So this code generates a 200 Hz clock based on a 100 Mhz clock.

We note that: 100 MHz / 500000 = 200 Hz

So, we need to take our 100 Mhz clock, and every 500000 cycles, we would have a full cycle of the 200 Hz clock that we would like to generate. Since we want the high time and low time to be the same, we know that we should oscillate the new clock every 500000 / 2 cycles.

From the perspective of the code, we will use hexadecimal, so it's worth noting that 500000 / 2 == 0x3D090.

architecture foo of blah is
    signal clk_200Hz : std_logic := '0';
    signal counter : unsigned(19 downto 0) := x"00000";
begin

    clkdiv : process (clk_100Mhz)
    begin
        if rising_edge(clk_100Mhz) then
            if counter = x"00000" then
                counter <= X"3D090"
                clk_200Hz <= not clk_200Hz;
            else
                counter <= counter - 1;
            end if;
        end if;
    end process clkdiv;

end architecture;