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_vectorfor 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
unsignedtype for counters to enable arithmetic. - Always check clock with
rising_edge(clk). - Reset counter asynchronously or synchronously as needed.
- Compare count with
N-1to reset. - Convert
unsignedtostd_logic_vectorfor 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.