Skip to content

Instantly share code, notes, and snippets.

@APadierna
Last active August 29, 2015 14:18
Show Gist options
  • Save APadierna/80672246477f00743475 to your computer and use it in GitHub Desktop.
Save APadierna/80672246477f00743475 to your computer and use it in GitHub Desktop.
Simple configurable VHDL counter block
----------------------------------------------------------------------
--! @brief
--! Simple configurable counter
--!
--! @details
--! counter the number of 'clk' rising edges defined by 'g_eoc'.
--! Once the EOC value is reached, this is indicated by the
--! activation of the 'eoc' signal.
--! The counter is restarted with the 'start' activation.
--! The counter may be configured with the 'g_cyclic' signal to
--! either restart when the count concludes or stay until an 'start'
--! activation is received.
--! The counter EOC value may be configured (when instanced) via the
--! 'g_eoc' generic
--!
--! @remarks
--! The designs adjust itself to the counter width required to reach
--! the defined end of count value (in compilation time).
--! Note that if the counter has been configured to execute cyclically,
--! the eoc signal will be active just for a 'clk' period.
----------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.conv_std_logic_vector;
use ieee.std_logic_unsigned.all;
use ieee.math_real.all;
entity counter is
generic(
g_cyclic : boolean := false; --! If true restarts counter when EOC is reached
g_eoc : integer := 10 --! End of count value
);
port(
clk : in std_logic; --! Module clock
reset_n : in std_logic; --! Module reset (active low)
start : in std_logic; --! Counter restart
enable : in std_logic; --! Counter enable
eoc : out std_logic --! End of count
);
end entity counter;
architecture rtl of counter is
constant c_width: integer := integer(ceil(log2(real(g_eoc))));
signal cnt: std_logic_vector(c_width-1 downto 0);
begin
----------------------------------------------------------------------
--! @brief
--! Regressive counter
----------------------------------------------------------------------
p_counter : process(clk, reset_n)
constant c_eoc : std_logic_vector := conv_std_logic_vector(g_eoc-1, cnt'length);
constant c_one : std_logic_vector := conv_std_logic_vector(1, cnt'length);
constant c_zero: std_logic_vector := conv_std_logic_vector(0, cnt'length);
begin
if reset_n = '0' then
cnt <= (others=>'0');
eoc <= '0';
elsif rising_edge(clk) then
if start='1' then
cnt <= c_eoc;
elsif enable='1' then
if cnt>c_zero then
cnt <= cnt - c_one;
elsif g_cyclic=true then
cnt <= c_eoc;
end if;
end if;
if cnt=c_zero then
eoc <= '1';
else
eoc <= '0';
end if;
end if;
end process p_counter;
end architecture rtl;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment