Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21584 Discussions

Using CPLD/FPGA as a Timer

Altera_Forum
Honored Contributor II
3,992 Views

Hi. 

 

I am interested to implement a timer that can count up to hours, in my FPGA/CPLD. The main purpose of the timer is to issue a pulse after a certain fixed duration, eg. every 2 hours. Normally I would use a counter to do this, if the period is not that long. But for the counter that can count up to hours, it needs too many LEs, since I am using a 5-MHz input clock.  

 

Is the any better way to do this, without using too many LEs? I would like to keep the 5-MHz clock if possible. Any idea is much appreciated. Thanks! 

 

Regards, 

CW
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
2,788 Views

Hello, 

 

basically, the simple fact that the system needs (2*3600*5e6) states can't be bypassed. ceil(log2((2*3600*5e6)-1)) = 36 gives the number of bits for a binary counter, which is always the minimal state representation, I think. 

 

Using a modified vhdl binary counter template with a MAX II CPLD, I got an overall LE consumption of 46. The 10 additional LE's are a tribute to the particular MAX_COUNT, a 2**N value would allow a simple ripple-carry counter. 

 

Best regards and Happy New Year! 

 

Frank 

 

-- Modified Quartus II VHDL Template -- Binary Counter library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity timer is generic ( MIN_COUNT : natural := 0; MAX_COUNT : natural := (5e6*3600*2)-1 ); port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; q : out std_logic ); end entity; architecture rtl of timer is begin process (clk) variable cnt : integer range MIN_COUNT to MAX_COUNT; begin if (rising_edge(clk)) then if reset = '1' then -- Reset the counter cnt := MIN_COUNT; q <= '0'; elsif enable = '1' then -- Increment the counter if counting is enabled if cnt < MAX_COUNT then cnt := cnt + 1; q <= '0'; else cnt:=MIN_COUNT; q <= '1'; end if; end if; end if; end process; end rtl;
0 Kudos
Altera_Forum
Honored Contributor II
2,788 Views

Hello, 

 

I just was aware, that the said MAX_COUNT overflows the integer range, thus my example is incorrect. Changing the count value to unsigned with full length, the LE consumption increases to 54. Sorry for the confusion. 

 

Frank 

 

-- Modified Quartus II VHDL Template -- Binary Counter library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity timer is generic ( MAX_COUNT : unsigned(35 downto 0) := x"861C467FF" ); port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; q : out std_logic ); end entity; architecture rtl of timer is begin process (clk) variable cnt : unsigned(35 downto 0); begin if (rising_edge(clk)) then if reset = '1' then -- Reset the counter cnt := (others => '0'); q <= '0'; elsif enable = '1' then -- Increment the counter if counting is enabled if cnt < MAX_COUNT then cnt := cnt + 1; q <= '0'; else cnt := (others => '0'); q <= '1'; end if; end if; end if; end process; end rtl; 

 

P.S.: Rounding MAX_COUNT to x"860000000", the LE consumption decreases to 41
0 Kudos
Altera_Forum
Honored Contributor II
2,788 Views

Thanks Frank. 

 

I guess without using a much slower clock, there is no way I can greatly reduce the amount of LEs used. 

 

Regards, 

CW
0 Kudos
Altera_Forum
Honored Contributor II
2,788 Views

how about pre-scaling at the output? say with few ripple-counter ICs and a D-flipflop to square the waveform duty cycle to 50%  

 

sure, a bit of a solder job but it may be easier than tinkering with the 5Mhz especially if you are using pre-fab board with all-SMD parts... 

 

~B
0 Kudos
Reply