Clock_Div

Discussion in 'VHDL' started by Volker, Dec 1, 2008.

  1. Volker

    Volker Guest

    Hi,

    following entity should divide a 50 MHz clock into 8khz, 2Hz and 1 Hz. In
    principle it would work, but 2 Hz clock is 1 Hz and the duty cycle ist about
    30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view the
    implementation of Q24 and Q25 looks a little bit strange. Did anyone know
    how the design ist not working well?

    Thanks
    Volker

    Code:
    -- DIV_COUNTER is a VHDL Design
    --
    -- Author: V.Meiss
    --
    -- Version 1.0 from 13.08.2008
    -- Altera QuartusII 8.0 SP1


    library IEEE;
    use IEEE.STD_LOGIC_1164.all;
    use IEEE.STD_LOGIC_ARITH.all;
    use IEEE.STD_LOGIC_UNSIGNED.all;


    entity DIV_COUNTER is
    port(CLK : in STD_LOGIC;
    CLK1, CLK2, CLK8k : out STD_LOGIC);
    end DIV_COUNTER;

    architecture BEHAVIOR of DIV_COUNTER is
    signal Q : std_logic_vector(25 downto 0);
    signal LOAD : STD_LOGIC;
    begin


    process(CLK, LOAD)
    constant PRESET : NATURAL :=50000000; -- input 50 MHz
    begin
    if (LOAD = '0') then
    Q <= CONV_STD_LOGIC_VECTOR(PRESET, 26);
    LOAD <= '1';
    elsif (CLK'EVENT and CLK='1') then
    Q <= Q - 1;
    end if;

    if (Q = "00000000000000000000000000") then
    LOAD <= '0';
    end if;

    CLK1 <= Q(25); -- 1HZ CLK
    CLK2 <= Q(24); -- 2HZ CLK
    CLK8k <= Q(12);-- 8 kHZ CLK
    end process;

    end BEHAVIOR;
    Volker, Dec 1, 2008
    #1
    1. Advertising

  2. Volker wrote:

    > In principle it would work, but 2 Hz clock is 1 Hz and the duty cycle
    > ist about 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view
    > the implementation of Q24 and Q25 looks a little bit strange. Did
    > anyone know how the design ist not working well?


    In principle, it *won't* work as you hope.

    The '1Hz' clock has 30/70 duty cycle because (2^25)/50e6 is about 70%.

    IMHO don't feed back an async preset from the process logic, just preset
    the counter explicitly. And your 1Hz clock should be asserted whenever Q
    reaches a certain (any) value. The other clocks don't divide nicely into
    50e6 so you can't really do what you're trying to do.

    I'd probably derive an 8KHz clock enable and use that to increment a
    counter that you can derive the 1Hz and 2Hz clock enables from... you're
    not clocking logic with these clocks, are you!?!

    Regards,

    --
    Mark McDougall, Engineer
    Virtual Logic Pty Ltd, <http://www.vl.com.au>
    21-25 King St, Rockdale, 2216
    Ph: +612-9599-3255 Fax: +612-9599-3266
    Mark McDougall, Dec 1, 2008
    #2
    1. Advertising

  3. Volker

    Enes Erdin Guest

    On 1 Aralýk, 06:15, "Volker" <> wrote:
    > Hi,
    >
    > following entity should divide a 50 MHz clock into 8khz, 2Hz and 1 Hz. In
    > principle it would work, but 2 Hz clock is 1 Hz and the duty cycle ist about
    > 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view the
    > implementation of Q24 and Q25 looks a little bit strange. Did anyone know
    > how the design ist not working well?
    >
    > Thanks
    > Volker
    >
    > Code:
    > -- DIV_COUNTER is a VHDL Design
    > --
    > -- Author: V.Meiss
    > --
    > -- Version 1.0 from 13.08.2008
    > -- Altera QuartusII 8.0 SP1
    >
    > library IEEE;
    > use IEEE.STD_LOGIC_1164.all;
    > use IEEE.STD_LOGIC_ARITH.all;
    > use IEEE.STD_LOGIC_UNSIGNED.all;
    >
    > entity DIV_COUNTER is
    >      port(CLK   : in STD_LOGIC;
    >            CLK1, CLK2, CLK8k : out STD_LOGIC);
    > end DIV_COUNTER;
    >
    > architecture BEHAVIOR of DIV_COUNTER is
    >      signal Q  : std_logic_vector(25 downto 0);
    >      signal LOAD  : STD_LOGIC;
    > begin
    >
    >  process(CLK, LOAD)
    >       constant PRESET : NATURAL :=50000000; -- input 50 MHz
    >  begin
    >       if (LOAD = '0') then
    >            Q <= CONV_STD_LOGIC_VECTOR(PRESET, 26);
    >            LOAD <= '1';
    >       elsif (CLK'EVENT and CLK='1') then
    >        Q <= Q - 1;
    >        end if;
    >
    >       if (Q = "00000000000000000000000000") then
    >        LOAD <= '0';
    >       end if;
    >
    >       CLK1 <= Q(25); -- 1HZ CLK
    >       CLK2 <= Q(24); -- 2HZ CLK
    >       CLK8k <= Q(12);-- 8 kHZ CLK
    >  end process;
    >
    > end BEHAVIOR;


    The duty cycle of 1 Hz is about 164/500 how did I calculate this?

    Try to write a code which counts a less number. The problem is that
    50_000_000 is something like 1011111010.. so when you say that Q(25)
    is a 1 Hz signal you will get a wrong result. the same applies for
    others too (also for 8 khz)

    If I were you I would create an enable signal to create a 8 Khz signal
    and using this enable signal I would create the clock signals for 1 Hz
    and 2 Hz signals by the help of another counter.

    Good luck.
    Enes Erdin, Dec 1, 2008
    #3
  4. Volker

    Enes Erdin Guest

    On 1 Aralýk, 06:51, Mark McDougall <> wrote:

    >
    > The '1Hz' clock has 30/70 duty cycle because (2^25)/50e6 is about 70%.
    >

    That's better :)
    Enes Erdin, Dec 1, 2008
    #4
  5. Volker

    Tricky Guest

    On 1 Dec, 14:15, "Volker" <> wrote:
    > Hi,
    >
    > following entity should divide a 50 MHz clock into 8khz, 2Hz and 1 Hz. In
    > principle it would work, but 2 Hz clock is 1 Hz and the duty cycle ist about
    > 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view the
    > implementation of Q24 and Q25 looks a little bit strange. Did anyone know
    > how the design ist not working well?
    >
    > Thanks
    > Volker
    >
    > Code:
    > -- DIV_COUNTER is a VHDL Design
    > --
    > -- Author: V.Meiss
    > --
    > -- Version 1.0 from 13.08.2008
    > -- Altera QuartusII 8.0 SP1
    >
    > library IEEE;
    > use IEEE.STD_LOGIC_1164.all;
    > use IEEE.STD_LOGIC_ARITH.all;
    > use IEEE.STD_LOGIC_UNSIGNED.all;
    >
    > entity DIV_COUNTER is
    >      port(CLK   : in STD_LOGIC;
    >            CLK1, CLK2, CLK8k : out STD_LOGIC);
    > end DIV_COUNTER;
    >
    > architecture BEHAVIOR of DIV_COUNTER is
    >      signal Q  : std_logic_vector(25 downto 0);
    >      signal LOAD  : STD_LOGIC;
    > begin
    >
    >  process(CLK, LOAD)
    >       constant PRESET : NATURAL :=50000000; -- input 50 MHz
    >  begin
    >       if (LOAD = '0') then
    >            Q <= CONV_STD_LOGIC_VECTOR(PRESET, 26);
    >            LOAD <= '1';
    >       elsif (CLK'EVENT and CLK='1') then
    >        Q <= Q - 1;
    >        end if;
    >
    >       if (Q = "00000000000000000000000000") then
    >        LOAD <= '0';
    >       end if;
    >
    >       CLK1 <= Q(25); -- 1HZ CLK
    >       CLK2 <= Q(24); -- 2HZ CLK
    >       CLK8k <= Q(12);-- 8 kHZ CLK
    >  end process;
    >
    > end BEHAVIOR;


    If you are using individual bits from a counter for your output clocks
    (as you are) you can only get a nice 50/50 mark space ratio on clocks
    outputs that are 1/2^n speeds. Using an asyncronous reset will just
    skew the duty cycle as you have seen. So as you have a 50MHz clock,
    you can only get a nice 50/50 duty cycle if you want 25Mhz, 12.5Hz,
    6.25MHz etc.

    As for the synthesisor implementing something odd, its probably
    because you have an asyncronous load, which is never a good idea. Ive
    built it myself, and yes, theres alot of unnessary logic. You also
    havent put Q in the sensitivity list so this code will not simulate
    properly (it wont reset when Q gets to 0, it will just wrap).

    I would recommend using a fully syncronous version:

    library IEEE;
    use IEEE.STD_LOGIC_1164.all;
    use ieee.numeric_std.all;

    entity DIV_COUNTER is
    port(CLK : in STD_LOGIC;
    CLK1, CLK2, CLK8k : out STD_LOGIC);
    end test_build;

    architecture BEHAVIOR of DIV_COUNTER is
    signal Q : unsigned(25 downto 0);
    begin

    process(CLK, LOAD)
    constant PRESET : NATURAL :=50000000; -- input 50 MHz
    begin

    if rising_edge(clk) then
    if Q = 0 then
    Q <= unsigned(PRESET)
    else
    Q <= Q - 1;
    end if;
    end if;


    CLK1 <= Q(25); -- 1HZ CLK
    CLK2 <= Q(24); -- 2HZ CLK
    CLK8k <= Q(12);-- 8 kHZ CLK
    end process;

    end BEHAVIOR;


    NOTE: It is HIGHLY recommended to use enables rather than logic-
    generated clocks on other registers.
    Tricky, Dec 1, 2008
    #5
  6. Volker

    Tricky Guest


    >         Q <= unsigned(PRESET)



    whooops, that should be:

    Q <= to_unsigned(PRESET, Q'length)
    Tricky, Dec 1, 2008
    #6
  7. Tricky wrote:

    > entity DIV_COUNTER is
    > port(CLK : in STD_LOGIC;
    > CLK1, CLK2, CLK8k : out STD_LOGIC);
    > end test_build;


    Make that "end div_counter;"

    >
    > NOTE: It is HIGHLY recommended to use enables rather than logic-
    > generated clocks on other registers.


    Clock enables can be implied for variable registers.
    For example:
    http://mysite.verizon.net/miketreseler/count_enable.vhd

    -- Mike Treseler
    Mike Treseler, Dec 1, 2008
    #7
  8. Volker

    Volker Guest

    Thanks for your answers,
    My problem is not the 50/50 duty cycle but that the 1HzCLK and the 2HzClk
    are at the same frequency (1Hz). Making the load synchronous will not help.
    Is there a limiting of type NATURAL?

    Thanks for help
    Volker

    "Mark McDougall" <> schrieb im Newsbeitrag
    news:...
    > Volker wrote:
    >
    >> In principle it would work, but 2 Hz clock is 1 Hz and the duty cycle
    >> ist about 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view
    >> the implementation of Q24 and Q25 looks a little bit strange. Did
    >> anyone know how the design ist not working well?

    >
    > In principle, it *won't* work as you hope.
    >
    > The '1Hz' clock has 30/70 duty cycle because (2^25)/50e6 is about 70%.
    >
    > IMHO don't feed back an async preset from the process logic, just preset
    > the counter explicitly. And your 1Hz clock should be asserted whenever Q
    > reaches a certain (any) value. The other clocks don't divide nicely into
    > 50e6 so you can't really do what you're trying to do.
    >
    > I'd probably derive an 8KHz clock enable and use that to increment a
    > counter that you can derive the 1Hz and 2Hz clock enables from... you're
    > not clocking logic with these clocks, are you!?!
    >
    > Regards,
    >
    > --
    > Mark McDougall, Engineer
    > Virtual Logic Pty Ltd, <http://www.vl.com.au>
    > 21-25 King St, Rockdale, 2216
    > Ph: +612-9599-3255 Fax: +612-9599-3266
    >
    Volker, Dec 9, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page