VHDL Counter
Quick Syntax
PROC_COUNTER : process (clk)
begin
if rising_edge(clk) then
if count = 1023 then
output <= '1';
count <= 0;
else
output <= '0';
count <= count + 1;
end if;
end if;
end process;
Purpose
Counters are used frequently in digital design. You can implement them with a clocked process using if statements.
You can do two different approaches:
1) Count up counter
2) Count down counter
The one you use usually depends on the type of interface that you are interacting with. It's often best to use the same numbering scheme that your interface uses so that it's much easier to get it right in code and simulation.
They are basically the same thing, except the start/end points and counting direction are opposite.
Because you need to add or subtract, you'll need a library included in your design. The recommended library is ieee.numeric_std.all, whereas older designs used ieee.std_logic_arith.all.
Personally, I prefer to type my counts as integers because it's allowed and super easy to deal with.
Examples
Count Up Counter:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
........
signal count : integer;
begin
PROC_UP_COUNTER : process (clk,reset)
begin
if rising_edge(clk) then
if reset = '1' then
output <= '0';
count <= 0;
else
if count = 255 then
output <= '1';
count <= 0;
else
output <= '0';
count <= count + 1;
end if;
end if;
end if;
end process;
Count Down Counter:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
........
signal count : integer;
begin
PROC_DOWN_COUNTER : process (clk,reset)
begin
if rising_edge(clk) then
if reset = '1' then
output <= '0';
count <= 255;
else
if count = 0 then
output <= '1';
count <= 255;
else
output <= '0';
count <= count - 1;
end if;
end if;
end if;
end process;
Best Practices
1. Make your counters with if statements where the if states the boundary of the count, and the else increments or decrements the count.
2. Always confirm that your boundary check also changes the count, otherwise your counter will get stuck there. Unless of course you just want it to run through it's range 1 time.
3. Match your up or down counter to the interface that you are working with so that it's much easier to verify your code in simulation.
4. You can add an elsif to your counter if you need a pulse to be a certain width, as it allows you to have two checks where you want the pulse to start and stop in relation to the count.