Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

Making a counter from 50MHz Clock?

Hi,

I know this might be a really silly question but I can't seem to get the theory down into HDL:

I want to make a 3579545Hz clock from a 50MHz clock input:

i know that

--- Quote Start ---

1/3579545 = 2.7936511484001458285899464876123e-7

Multiply that by 1000,000 and get 279.36511484001458285899464876123ns

--- Quote End ---

:D

but how i use this info to make a clock? that's another story.

I've tried just using a PLL, but it didnt like my desired output. I'm thinking it was in the wrong format but i don't know for sure.

In the megawizard, i told it that my input clock was 50MHz. the output could only be in MHz ps or ns. of course it did not like my desired output saying that tthe requested multiply/div factors were not achievable.

could someone please help?

P.S.

I tried reading the ALTPLL.pdf but it was very hard to do

14 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Sorry,

    Work and school got a bit overwhelming...

    I'm able to spend a few days working on some VHDL now :)

    I will try to comment your code to confirm i understand it.

    --- Quote Start ---

    
    process(clk)
    variable count : unsigned(26 downto 0) := (others => '0');  //why others => '0'?
    begin
    if rising_edge(clk) then
        if count > 50000000-1 then
             count := count - 50000000;    //set count to 0
        else
             count := count + 3579545;     //very clever "modulo" does it really work as such?
        end if;
        my_clk <= std_logic(count(25));  //passes bit 25 and uses as a clock signal
    end if;
    end process;
    

    --- Quote End ---

    thanks for your help!!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The "others => '0' is equivalent to writing:

    count := "000000000000000000000000000"; -- and I lost how many zeros.

    The subtraction is not to reset count to zero and you shouldn't. Instead you wrap up and keep difference from zero (count phase).

    To understand it better take case of generating 21MHz from 50MHz clock.

    the ratio factorises to 21/50 so:

    0, + 21, + 21, + 21, + 21, + 21,... =

    0, 21, 42, 63, 84, 105... and with modulo 50 =

    0, 21, 42, 13, 34, 5...

    0, 0, 1, 0, 1, 0... MSB will togle at 0.5 or more of count value
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Wow. Clever trick. I hope that I can keep enough consistent practice to have tricks like that up my sleeve whenever ready. Thanks!!

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Wrong, I am afraid.

    choose counter of 26 bits (to cover 50 million) and I will add extra bit for overflow protection. I prefer to use variable here so that the count is corrected before it is too late.

    
    process(clk)
    variable count : unsigned(26 downto 0) := (others => '0');
    begin
    if rising_edge(clk) then
        if count > 50000000-1 then
             count := count - 50000000;
        else
             count := count + 3579545;
        end if;
        my_clk <= std_logic(count(25));
    end if;
    end process;
    

    --- Quote End ---

    goooooooooooooooooood