Forum Discussion

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

Counting on falling and rising edge of clock

hi is it possible to design

dual edge counter in altera , what which is possible in xilinx cool runner series

reagards

baba

-- Xilinx ---

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_arith.all;

entity CNT2 is

port( data : in STD_LOGIC_VECTOR (1 downto 0); -- Parallel data in

cnt_en : in STD_LOGIC; -- Count enable

load : in STD_LOGIC; -- Load line enable

clr : in STD_LOGIC; -- Active low clear

clk : in STD_LOGIC; -- Clock

qout : inout STD_LOGIC_VECTOR (1 downto 0));

end CNT2;

architecture rtl of CNT2 is

signal q_int : UNSIGNED (1 downto 0);

begin

process(clk, clr)

begin -- Clear output register

if (clr = '0') then q_int <= (others => '0');-- Counting on falling and rising edge of clock

elsif clk'event then

if (load = '1') then q_int <= UNSIGNED(data);-- Load in start value

elsif cnt_en = '1' then q_int <= q_int + 1;-- If count enable is high

end if;

end if;

end process;

qout <= STD_LOGIC_VECTOR(q_int);

end rtl;

-- Altera i changed it like this --

library IEEE;

use IEEE.STD_LOGIC_1164.all;

use IEEE.STD_LOGIC_arith.all;

use IEEE.STD_LOGIC_unsigned.all;

entity dual is

port( cnt_en : in STD_LOGIC;

data : in STD_LOGIC_VECTOR (7 downto 0);

load : in STD_LOGIC;

clr : in STD_LOGIC;

clk : in STD_LOGIC;

qout : inout STD_LOGIC_VECTOR (7 downto 0));

end dual;

architecture rtl of dual is

signal q_int_o,q_int_e : UNSIGNED (7 downto 0);

begin

process(clk, clr)

begin

if (clr = '0') then q_int_o <= "00000001";

elsif clk'event and clk='1' then

if (load = '1') then

if data(0) ='1' then q_int_o <= UNSIGNED(data);

else q_int_o <= UNSIGNED(data)+1;

end if;-- Load in start value

elsif cnt_en = '1' then q_int_o <= q_int_o + 2;-- If count enable is high

end if;

end if;

end process;

process(clk, clr)

begin

if (clr = '0') then q_int_e <= (others => '0');

elsif clk'event and clk='0' then

if (load = '1') then

if data(0) ='0' then q_int_e <= UNSIGNED(data);

else q_int_e <= UNSIGNED(data)-1;

end if;

elsif cnt_en = '1' then q_int_e <= q_int_e + 2;end if;

end if;

end process;

qout <= STD_LOGIC_VECTOR(q_int_e) when clk='0' else STD_LOGIC_VECTOR(q_int_o) when clk='1';

end rtl;

4 Replies

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

    How is this done in Xilinx? I had someone target this for V5 in ISE, and after cleaning up the errors(entity changes from CNT to CNT2, and RESET_ACTIVE is undefined), it errors out with "unsupported clock statement".

    If your device has a PLL, you can create a 2x clock and use that for the counter. If there isn't, you can have a counter that counts on the rising edge, and then add an LSB that is the inversion of the clock(This requires you to understand the timing analysis that occurs, and really depends on what this counter feeds and what you're actually trying to show...)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Ahh, I didn't know that. (I used to work for X, but that was before they acquired Coolrunner, so I don't know much about that family. I was pretty sure the rest didn't support that.). If that's what you're targeting, then you're probably looking at an Altera device that doesn't have a PLL in it. But if it's purely a counter, then the lowest bit is purely a reflection of the clock(or the inverse of it, depending when you start the counter). I'm guessing you need more than a counter to have rise+fall capabilities?

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

    You could use a circuit , which doubles the frequency. Xilinx has it online on their sites AFAIK. The circuit produces a small spike at every signal edge. This should do.