A modulo counter is a counter that wraps around when it reaches a certain value. For example, a counter modulo 5 will count 0, 1, 2, 3, 4, 0, 1, … ; namely, after 4 it will wrap around to 0. The reason the counter wraps at 4 is because, to count five clock pulses starting from zero, the maximum value of the counter must be (modulo-1).

Every VHDL counter is a modulo counter. If you define a two bit counter, it will wrap around automatically from 3 to 0 without the need of writing special logic for that.

But what if we want a modulo counter that is different from a power of 2? In that case we have to write special logic to achieve that.

The code below implements a modulo counter. The counter width is defined as a generic parameter. The modulo value is an input to the module. Tipically, this value will come from a registers blocks, updated by a processor host.

We may notice that the implementation is as a down-counter and not an up-counter. For Altera devices (at least for those I have tested), the implementation as a down-counter is more efficient (regarding HW resources utilization) than an implementation as up-counter.

The entity includes the * DATA_W *parameter, namely, the size of the counter. The

**input is the modulo value. The component also has an enable input (**

*max_cnt**), and the*

**en***output which is asserted when the counter value is zero.*

**zero**Here we can see the implementation architecture of the modulo counter:

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity modulo_cnt is generic ( DATA_W : natural := 32 ); port ( clk: in std_logic; rst: in std_logic; -- inputs max_cnt: in std_logic_vector (DATA_W-1 downto 0); en: in std_logic; -- outputs zero: out std_logic ); end modulo_cnt; architecture rtl of modulo_cnt is signal cnt : unsigned(DATA_W-1 downto 0); signal zero_i : std_logic; begin zero_i <= '1' when cnt = 0 else '0'; zero <= zero_i; counter_pr: process (clk, rst) begin if (rst = '1') then cnt <= (others => '0'); elsif (rising_edge(clk)) then if (en = '1') then -- is counting enabled? if (zero_i = '1') then -- check if counter reached zero cnt <= unsigned(max_cnt) - 1; -- reload with modulo value else cnt <= cnt - 1; -- decrement counter end if; end if; end if; end process; end rtl;

The logic is very simple to follow. The counting logic is enabled by the ** en** input. If

**is asserted and the counter**

*en***reaches zero, it is re-loaded with the**

*cnt***input value. Otherwise, the**

*max_cnt**is decremented.*

**cnt**On the following waveform from the simulation we can see the operation of the modulo counter.

On the first cursor, the ** en **input is asserted. From the next clock, we can see that the counter counts down until it reaches zero, where the

*ouput is asserted and the counting resumes from the (*

**zero***-1) value.*

**max_cnt**On the second figure, the * max_cnt *is six. Exactly after the zero output is asserted the counter is disables (first cursor), so we see that for several clocks the counting value on

*doesn’t change. The second cursor marks the time where the counter (now enabled for several clocks) reaches zero and wraps around to five (=*

**cnt***-1).*

**max_cnt**The sources, testbench files, waveform, simulation project files, etc., are released under Github.

Link for this project on Github

Link for all releases of this project under Github