8254 mode 2 divide by n counter

Discussion in 'VHDL' started by least.square, Apr 3, 2011.

  1. least.square

    least.square

    Joined:
    Apr 3, 2011
    Messages:
    4
    Hi, I'm losing it or seriously lacking sleep.

    I have a simple circuit that is to be driven by a timer output similar to an 8254 operating in mode 2. So simple its unbelievable. However I synthesis the code below and the falling edge of clkout is always generated when the count is 0. If modulus is loaded with 3 then I expect so 3,2,1,3,2,1 repeating with the clkout going low on 1 and coming high on 0 as the reload occurs.

    clkout is delayed one clock. Now I realise this due to the signal queue, however if I set clkout low when count = 2 it make no difference. In fact irrespective of the compare & reload value clkout always go low when the count is 0.

    Any ideas anyone?


    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_arith.all;
    use ieee.std_logic_unsigned.all;
    use ieee.numeric_std.all;


    entity CLOCK_DIVIDER is
    port(
    reset: in std_logic;
    clk: in std_logic;
    modulus:in std_logic_vector (15 downto 0); -- modulo divider
    enable: in std_logic;
    clkout: out std_logic -- divided output
    );
    end entity;


    architecture RTL of CLOCK_DIVIDER is

    begin

    pDivide: process(clk, reset, enable)

    variable count: natural;

    begin
    if (reset = '0') then
    count := 0;
    clkout <= '1';
    elsif falling_edge(clk) then
    if (enable = '1') then
    if (count = 1) then
    clkout <= '0';
    elsif (count = 0)
    clkout <= '1';
    count = modulus;
    else
    count := count - 1;
    end if;
    else
    count := count;
    end if;
    end if;
    end process;

    end architecture RTL;
     
    least.square, Apr 3, 2011
    #1
    1. Advertising

  2. least.square

    least.square

    Joined:
    Apr 3, 2011
    Messages:
    4
    sorry for the typo, I'm aware of the missing 'then'
     
    least.square, Apr 3, 2011
    #2
    1. Advertising

  3. least.square

    least.square

    Joined:
    Apr 3, 2011
    Messages:
    4
    not a good start... I copy and pasted the an early iteration of the rtl. Below is the coder I'm running. I want the same functionality as described earlier.

    Changing x in the compare below make to change to when the output is asserted low. This I don't understand.

    if (count = to_integer(unsigned(modulus - x))) then


    pDivide: process(clk, reset, enable)

    variable count: natural;

    begin
    if (reset = '0') then
    count := 0;
    clkout <= '1';
    elsif falling_edge(clk) then
    if (enable = '1') then
    if (count = to_integer(unsigned(modulus))) then
    count := 0;
    else
    count := count + 1;
    end if;
    else
    count := count;
    end if;

    if (count = to_integer(unsigned(modulus - 2))) then
    clkout <= '0';
    else
    clkout <= '1';
    end if;
    end if;
    end process;
     
    least.square, Apr 3, 2011
    #3
  4. least.square

    least.square

    Joined:
    Apr 3, 2011
    Messages:
    4
    a few hours sleep did the trick...
    posted the code for review and/or use

    cheers,
    :fisheye:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_arith.all;
    use ieee.std_logic_unsigned.all;
    use ieee.numeric_std.all;


    entity CLOCK_DIVIDER is
    port(
    reset: in std_logic; -- device reset
    clk: in std_logic; -- device clock as it run synchronous to system clock
    modulus:in std_logic_vector (15 downto 0); -- modulo divider
    enable: in std_logic; -- enable device
    clkout: out std_logic -- divided clock output
    );
    end entity;


    architecture RTL of CLOCK_DIVIDER is

    signal eSync: std_logic;
    signal eSyncP: std_logic;

    begin

    pDivide: process(clk, reset, enable)

    variable count: natural;
    variable reload: natural;

    begin
    if (reset = '0') then
    clkout <= '1';
    elsif falling_edge(clk) then
    eSync <= enable;
    eSyncP <= eSync;

    -- catch rising edge of timer being started and
    -- set counter with reload value & deassert output
    if ((eSync = '1') and (eSyncP = '0')) then
    reload := to_integer(unsigned(modulus)); -- load the counter
    count := reload;
    elsif (enable = '1') then
    count := count - 1;
    if (count = 1) then
    clkout <= '0';
    elsif (count = 0) then
    clkout <= '1';
    count := reload;
    end if;
    else
    count := count;
    end if;
    end if;
    end process;


    end architecture RTL;
     
    least.square, Apr 3, 2011
    #4
    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.
Similar Threads
  1. Ash12

    Divide by 2 counter

    Ash12, Feb 27, 2005, in forum: VHDL
    Replies:
    2
    Views:
    6,197
    aaaaaa
    Feb 28, 2005
  2. John J Lee
    Replies:
    3
    Views:
    492
    bruno at modulix
    Dec 1, 2005
  3. Edward Loper
    Replies:
    0
    Views:
    478
    Edward Loper
    Aug 7, 2007
  4. John J Lee
    Replies:
    0
    Views:
    531
    John J Lee
    Aug 7, 2007
  5. Edward Loper

    mmm-mode, python-mode and doctest-mode?

    Edward Loper, Aug 9, 2007, in forum: Python
    Replies:
    0
    Views:
    441
    Edward Loper
    Aug 9, 2007
Loading...

Share This Page