------------------------------------------------------------------------------- -- counter.vhd -- Sydney Tang -- created: 1998 October 16 -- -- A general counter entity, customizable and loadable. -- -- 22 (1%) logic cells, 22.0ns, 45.45MHz without bounds checking -- 29 logic cells, 20.8ns, 48.07MHz with bounds checking on load -- -- The counter is designed so that the programmer can customize its width and -- the range of values that it may have. Width is set by COUNTER_WIDTH, and -- maxima and minima can be changed on the fly with Max_Count and Min_Count. -- -- The counter is also loadable. If load_enable is high, whatever is in -- input_count will become the new value of the counter. load_enable takes -- precedence over count_enable. -- -- If a loaded value is outside of the range specified by Max_Count and -- Min_Count, the counter will just keep on counting as if nothing was wrong. -- Eventually, as it progresses through all the possible counter values, -- it will back into range and stay in range. -- -- Incrementing the counter is accomplished by setting count_enable high, and -- resetting its value to Min_Count can be done by waiting for it to count past -- Max_Count or by setting reset high. If it overflows on a count_enable, the -- overflow output will be high for one clock cycle. ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; package Counter_Package is component counter is generic( COUNTER_WIDTH: positive := 4 ); port( clock: in std_logic; reset: in std_logic; overflow: out std_logic; count_enable: in std_logic; load_enable: in std_logic; input_count: in std_logic_vector(COUNTER_WIDTH-1 downto 0); Min_Count: in std_logic_vector(COUNTER_WIDTH-1 downto 0); Max_Count: in std_logic_vector(COUNTER_WIDTH-1 downto 0); count: out std_logic_vector(COUNTER_WIDTH-1 downto 0) ); end component counter; end package Counter_Package; ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity counter is generic( COUNTER_WIDTH: positive := 4 ); port( clock: in std_logic; reset: in std_logic; overflow: out std_logic; count_enable: in std_logic; load_enable: in std_logic; input_count: in std_logic_vector(COUNTER_WIDTH-1 downto 0); Min_Count: in std_logic_vector(COUNTER_WIDTH-1 downto 0); Max_Count: in std_logic_vector(COUNTER_WIDTH-1 downto 0); count: out std_logic_vector(COUNTER_WIDTH-1 downto 0) ); end counter; ------------------------------------------------------------------------------- architecture behaviour of counter is signal counter_value: std_logic_vector(COUNTER_WIDTH-1 downto 0); begin count <= counter_value; sync: process(clock) is begin if rising_edge(clock) then if reset = '1' then counter_value <= Min_Count; overflow <= '0'; elsif load_enable = '1' then -- if (input_count > Max_Count) or (input_count < Min_Count) then -- counter_value <= counter_value; -- else counter_value <= input_count; -- end if; elsif count_enable = '1' then if (counter_value = Max_Count) then -- restart and indicate overflow counter_value <= Min_Count; overflow <= '1'; else -- increment normally counter_value <= counter_value + '1'; overflow <= '0'; end if; else counter_value <= counter_value; overflow <= '0'; end if; -- reset | load | count | else end if; -- rising clock edge end process sync; end behaviour;