------------------------------------------------------------------------------- -- BCDtwoDigitCounter.vhd -- Sydney Tang -- created: 1998 October 29 -- -- 46 (3%) logic cells, 30.0ns, 33.33MHz without bounds checking (8.1) -- 46 (3%) logic cells, 27.9ns, 35.84MHz without bounds checking (7.21) -- 64 (5%) logic cells, 26.0ns, 38.46MHz with bounds checking on load (8.1) -- 64 (5%) logic cells, 20.4ns, 32.89MHz with bounds checking on load (7.21) -- -- A two-digit BCD counter entity, customizable and loadable. -- -- The counter is designed so that the programmer can customize -- 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 get 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; library work; use work.BCD_Package.all; entity BCDtwoDigitCounter is port( clock: in std_logic; reset: in std_logic; Min_Count: in std_logic_vector(2*BCD_WIDTH-1 downto 0); Max_Count: in std_logic_vector(2*BCD_WIDTH-1 downto 0); load_enable: in std_logic; input_count: in std_logic_vector(2*BCD_WIDTH-1 downto 0); count_enable: in std_logic; count: out std_logic_vector(2*BCD_WIDTH-1 downto 0); overflow: out std_logic ); end BCDtwoDigitCounter; ------------------------------------------------------------------------------- architecture behaviour of BCDtwoDigitCounter is signal counter_value: std_logic_vector(2*BCD_WIDTH-1 downto 0); signal digit1: std_logic_vector(BCD_WIDTH-1 downto 0); signal digit0: std_logic_vector(BCD_WIDTH-1 downto 0); begin counter_value(2*BCD_WIDTH-1 downto BCD_WIDTH) <= digit1; counter_value(BCD_WIDTH-1 downto 0) <= digit0; count <= counter_value; sync: process(clock) is begin if rising_edge(clock) then if reset = '1' then digit1 <= Min_Count(2*BCD_WIDTH-1 downto BCD_WIDTH); digit0 <= Min_Count(BCD_WIDTH-1 downto 0); overflow <= '0'; elsif load_enable = '1' then -- if -- -- counter value is out of range -- (input_count > Max_Count) or (input_count < Min_Count) -- then -- -- restart, no overflow -- digit1 <= Min_Count(2*BCD_WIDTH-1 downto BCD_WIDTH); -- digit0 <= Min_Count(BCD_WIDTH-1 downto 0); -- else digit1 <= input_count(2*BCD_WIDTH-1 downto BCD_WIDTH); digit0 <= input_count(BCD_WIDTH-1 downto 0); -- end if; elsif count_enable = '1' then if -- counter value == Max_Count counter_value = Max_Count then -- restart and indicate overflow digit1 <= Min_Count(2*BCD_WIDTH-1 downto BCD_WIDTH); digit0 <= Min_Count(BCD_WIDTH-1 downto 0); overflow <= '1'; else -- increment normally -- if(digit[0] == 9) -- ( -- digit[0] = 0; -- digit[1]++; -- } -- else -- digit[0]++; -- overflow = 0; if digit0 = BCD_MAX then digit0 <= BCD_MIN; digit1 <= digit1 + '1'; else digit0 <= digit0 + '1'; end if; overflow <= '0'; end if; else digit1 <= digit1; digit0 <= digit0; overflow <= '0'; end if; -- reset | load | count | else end if; -- rising clock edge end process sync; end behaviour;