Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   VHDL (http://www.velocityreviews.com/forums/f18-vhdl.html)
-   -   8254 mode 2 divide by n counter (http://www.velocityreviews.com/forums/t746272-8254-mode-2-divide-by-n-counter.html)

least.square 04-03-2011 12:20 PM

8254 mode 2 divide by n counter
 
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 04-03-2011 12:26 PM

sorry for the typo, I'm aware of the missing 'then'

least.square 04-03-2011 12:38 PM

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 04-03-2011 06:10 PM

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;


All times are GMT. The time now is 12:50 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.