VHDL Code for Ring Counter: Syntax and Example
A
ring counter in VHDL is a sequential circuit where a single '1' bit circulates through a register. You can implement it using a process with a clock and reset, shifting the '1' bit through a vector. The VHDL code typically uses a signal of type std_logic_vector and updates it on each clock cycle.Syntax
A ring counter in VHDL uses a std_logic_vector to hold the bits. It requires a clock and reset signal. On each rising clock edge, the '1' bit shifts to the next position, wrapping around to the start.
- clk: Clock input to trigger state changes.
- reset: Resets the counter to initial state.
- q: Output vector showing the current position of the '1'.
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ring_counter is
Port (
clk : in std_logic;
reset : in std_logic;
q : out std_logic_vector(3 downto 0)
);
end ring_counter;
architecture Behavioral of ring_counter is
signal count : std_logic_vector(3 downto 0);
begin
process(clk, reset)
begin
if reset = '1' then
count <= "0001"; -- initial position of '1'
elsif rising_edge(clk) then
count <= count(count'left-1 downto 0) & count(count'left);
end if;
end process;
q <= count;
end Behavioral;Example
This example shows a 4-bit ring counter that cycles a single '1' through four bits. The reset sets the output to "0001". On each clock pulse, the '1' moves one position to the left, wrapping around.
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ring_counter is
Port (
clk : in std_logic;
reset : in std_logic;
q : out std_logic_vector(3 downto 0)
);
end ring_counter;
architecture Behavioral of ring_counter is
signal count : std_logic_vector(3 downto 0);
begin
process(clk, reset)
begin
if reset = '1' then
count <= "0001";
elsif rising_edge(clk) then
count <= count(count'left-1 downto 0) & count(count'left);
end if;
end process;
q <= count;
end Behavioral;Output
At reset: q = 0001
After 1 clock: q = 0010
After 2 clocks: q = 0100
After 3 clocks: q = 1000
After 4 clocks: q = 0001 (wraps around)
Common Pitfalls
Common mistakes when writing a ring counter in VHDL include:
- Not initializing the counter properly on reset, causing undefined output.
- Incorrect bit shifting direction, which breaks the ring pattern.
- Forgetting to use
rising_edge(clk)for clock detection. - Using a vector size that does not match the intended ring length.
Always verify the reset state and test the wrap-around behavior.
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Wrong: No reset initialization
entity ring_counter_wrong is
Port (
clk : in std_logic;
q : out std_logic_vector(3 downto 0)
);
end ring_counter_wrong;
architecture Behavioral of ring_counter_wrong is
signal count : std_logic_vector(3 downto 0) := "0000"; -- no '1' set
begin
process(clk)
begin
if rising_edge(clk) then
count <= count(count'left-1 downto 0) & count(count'left);
end if;
end process;
q <= count;
end Behavioral;
-- Right: Proper reset and initialization
entity ring_counter_right is
Port (
clk : in std_logic;
reset : in std_logic;
q : out std_logic_vector(3 downto 0)
);
end ring_counter_right;
architecture Behavioral of ring_counter_right is
signal count : std_logic_vector(3 downto 0);
begin
process(clk, reset)
begin
if reset = '1' then
count <= "0001";
elsif rising_edge(clk) then
count <= count(count'left-1 downto 0) & count(count'left);
end if;
end process;
q <= count;
end Behavioral;Quick Reference
- Use
std_logic_vectorto hold the ring bits. - Initialize with a single '1' on reset.
- Shift bits on each rising clock edge.
- Wrap the shifted bit around to form a ring.
- Test reset and wrap-around behavior carefully.
Key Takeaways
Initialize the ring counter with a single '1' on reset to avoid undefined states.
Use rising_edge(clk) to update the counter on each clock cycle.
Shift the bits circularly to move the '1' around the ring.
Ensure the vector size matches the number of states in the ring.
Test the counter to confirm the '1' wraps around correctly after the last bit.