0
0
VhdlHow-ToBeginner · 3 min read

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_vector to 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.