8254 mode 2 divide by n counter

Joined
Apr 3, 2011
Messages
4
Reaction score
0
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;
 
Joined
Apr 3, 2011
Messages
4
Reaction score
0
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;
 
Joined
Apr 3, 2011
Messages
4
Reaction score
0
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;
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top