Last active
August 29, 2015 14:18
-
-
Save APadierna/80672246477f00743475 to your computer and use it in GitHub Desktop.
Simple configurable VHDL counter block
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
---------------------------------------------------------------------- | |
--! @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