VHDL Code for BCD Counter: Syntax and Example
A
BCD counter in VHDL counts from 0 to 9 in binary-coded decimal format and then resets. You can implement it using a process triggered by a clock and reset signal, incrementing the count and resetting after 9. The counter output is a 4-bit vector representing the decimal digit in binary.Syntax
The basic syntax for a BCD counter in VHDL includes defining an entity with clock and reset inputs and a 4-bit output. Inside the architecture, a process sensitive to the clock and reset signals increments the count on each clock rising edge and resets it when it reaches 9 or when reset is active.
- entity: Declares inputs and outputs.
- architecture: Contains the logic.
- process: Runs on clock and reset changes.
- if rising_edge(clock): Detects clock ticks.
- count <= count + 1: Increments the counter.
- if count = 9 then count <= 0: Resets after 9.
vhdl
entity BCD_Counter is
Port (
clk : in std_logic;
reset : in std_logic;
count : out std_logic_vector(3 downto 0)
);
end BCD_Counter;
architecture Behavioral of BCD_Counter is
signal cnt : unsigned(3 downto 0) := (others => '0');
begin
process(clk, reset)
begin
if reset = '1' then
cnt <= (others => '0');
elsif rising_edge(clk) then
if cnt = "1001" then -- 9 in binary
cnt <= (others => '0');
else
cnt <= cnt + 1;
end if;
end if;
end process;
count <= std_logic_vector(cnt);
end Behavioral;Example
This example shows a complete BCD counter that counts from 0 to 9 repeatedly. It uses a clock and asynchronous reset. The output count is a 4-bit vector representing the current decimal digit in binary.
vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity BCD_Counter is
Port (
clk : in std_logic;
reset : in std_logic;
count : out std_logic_vector(3 downto 0)
);
end BCD_Counter;
architecture Behavioral of BCD_Counter is
signal cnt : unsigned(3 downto 0) := (others => '0');
begin
process(clk, reset)
begin
if reset = '1' then
cnt <= (others => '0');
elsif rising_edge(clk) then
if cnt = "1001" then
cnt <= (others => '0');
else
cnt <= cnt + 1;
end if;
end if;
end process;
count <= std_logic_vector(cnt);
end Behavioral;Output
On each rising clock edge, the output count increments from 0000 to 1001 (0 to 9 in binary) then resets to 0000.
Common Pitfalls
Common mistakes when writing a BCD counter in VHDL include:
- Forgetting to reset the counter to zero after reaching 9, causing it to count beyond BCD range.
- Not using
rising_edge(clk)properly, which can cause simulation or synthesis issues. - Mixing
std_logic_vectorandunsignedtypes without proper conversion. - Using synchronous reset but coding it as asynchronous, or vice versa, leading to unexpected behavior.
Always convert between unsigned and std_logic_vector when doing arithmetic.
vhdl
Wrong approach:
process(clk)
begin
if reset = '1' then -- Incorrect: reset checked inside clock only
cnt <= (others => '0');
elsif rising_edge(clk) then
if cnt = "1001" then
cnt <= (others => '0');
else
cnt <= cnt + 1;
end if;
end if;
end process;
Right approach:
process(clk, reset)
begin
if reset = '1' then -- Asynchronous reset outside clock edge
cnt <= (others => '0');
elsif rising_edge(clk) then
if cnt = "1001" then
cnt <= (others => '0');
else
cnt <= cnt + 1;
end if;
end if;
end process;Quick Reference
Tips for writing a BCD counter in VHDL:
- Use
unsignedtype for arithmetic operations. - Check for
rising_edge(clk)to detect clock ticks. - Reset asynchronously for immediate reset response.
- Reset counter to zero after reaching 9 (BCD max).
- Convert
unsignedtostd_logic_vectorfor output ports.
Key Takeaways
Use a process triggered by clock and reset to implement the BCD counter logic.
Reset the counter to zero after it reaches 9 to keep it within BCD range.
Use the unsigned type for counting and convert to std_logic_vector for output.
Check for rising_edge(clk) to increment the counter correctly.
Avoid mixing synchronous and asynchronous reset styles incorrectly.