0
0
VhdlHow-ToBeginner · 3 min read

VHDL Code for Mod N Counter: Syntax and Example

A mod N counter in VHDL counts from 0 up to N-1 and then resets to 0. You create it using a process triggered by a clock, incrementing a signal and resetting it when it reaches N. The counter uses the mod operator or conditional reset to cycle through values.
📐

Syntax

A mod N counter in VHDL typically uses a process block sensitive to the clock and optionally reset signals. Inside, a signal representing the count is incremented each clock cycle and reset to zero when it reaches N.

  • signal count: holds the current count value.
  • process(clk, reset): triggers on clock edge or reset.
  • if rising_edge(clk): checks for clock rising edge.
  • if count = N-1 then count <= 0; resets counter.
  • else count <= count + 1; increments counter.
vhdl
process(clk, reset)
begin
  if reset = '1' then
    count <= 0;
  elsif rising_edge(clk) then
    if count = N-1 then
      count <= 0;
    else
      count <= count + 1;
    end if;
  end if;
end process;
💻

Example

This example shows a mod 10 counter that counts from 0 to 9 and then resets to 0 on each rising clock edge. It includes asynchronous reset.

vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity mod10_counter is
  Port (
    clk   : in  STD_LOGIC;
    reset : in  STD_LOGIC;
    count : out STD_LOGIC_VECTOR (3 downto 0)
  );
end mod10_counter;

architecture Behavioral of mod10_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 = to_unsigned(9, cnt'length) then
        cnt <= (others => '0');
      else
        cnt <= cnt + 1;
      end if;
    end if;
  end process;

  count <= std_logic_vector(cnt);
end Behavioral;
Output
The counter output cycles from 0000 to 1001 (0 to 9 in binary) repeatedly on each clock rising edge.
⚠️

Common Pitfalls

Common mistakes when writing mod N counters in VHDL include:

  • Not resetting the counter properly, causing unpredictable start values.
  • Using std_logic_vector for arithmetic without conversion, leading to errors.
  • Forgetting to check the clock edge with rising_edge(clk).
  • Incorrectly comparing the count value with N-1 without proper type conversion.

Always use unsigned or integer types for counting and convert to std_logic_vector only for output.

vhdl
Wrong approach:
process(clk)
begin
  if clk = '1' then -- Incorrect clock check
    if count = "1001" then -- Comparing std_logic_vector directly
      count <= "0000";
    else
      count <= count + 1; -- Arithmetic on std_logic_vector causes error
    end if;
  end if;
end process;

Correct approach:
process(clk, reset)
begin
  if reset = '1' then
    cnt <= (others => '0');
  elsif rising_edge(clk) then
    if cnt = to_unsigned(9, cnt'length) then
      cnt <= (others => '0');
    else
      cnt <= cnt + 1;
    end if;
  end if;
end process;
📊

Quick Reference

  • Use unsigned type for counters to enable arithmetic.
  • Always check clock with rising_edge(clk).
  • Reset counter asynchronously or synchronously as needed.
  • Compare count with N-1 to reset.
  • Convert unsigned to std_logic_vector for output ports.

Key Takeaways

Use a process triggered by clock and reset signals to implement a mod N counter in VHDL.
Use the unsigned type for counting and convert to std_logic_vector only for output.
Reset the counter when it reaches N-1 to cycle back to zero.
Always check the clock edge with rising_edge(clk) to avoid timing errors.
Avoid arithmetic directly on std_logic_vector without conversion.