I'm pretty new to VHDL (and digital circuits in general), and I'm trying to implement a counter of two digits using BCD style blocks. External to this circuit there is going to be buttons, which when pressed, will bump the digit of interest up by one (much like an alarm clock would). This is an asynchronous action, and will occur when in some form of edit mode (externally enforced). The code I have written works fine without the "elsif rising_edge(digitUp1) then" and "elsif rising_edge(digitUp1) then" blocks, but fails with them included. I really have no idea why it doesn't work or how I can fix it. Keep getting errors like "couldn't implement registers for assignments on this clock edge", "can't infer register for count2[3] because its behavior depends on the edges of multiple distinct clocks" and "Can't infer register for "count2[3]" at MinuteCounter.vhd(21) because it does not hold its value outside the clock edge". Any help would be greatly appreciated.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
-- ToDo: ENFORCE ON ALL COUNTERS (externally) LOGIC TO PAUSE AT MAX/MIN
entity MinuteCounter is
port( clockIn, digitUp1, digitUp2, reset, counting, countUp : in std_logic;
clockOut : out std_logic;
BCD1, BCD2 : out std_logic_vector(3 downto 0));
end MinuteCounter;
architecture structure of MinuteCounter is
signal count1, count2 : std_logic_vector(3 downto 0);
signal carryOut : std_logic;
begin
process( clockIn, digitUp1, digitUp2, countUp, reset, counting)
begin
-- Asynchronous reset
if reset = '1' then
count1 <= "0000";
count2 <= "0000";
-- What to run when there's an active edge of the clock
elsif rising_edge(clockIn) then
-- Code to run when timer is running
if counting = '1' then
-- What to do when counting up
if countUp = '1' then
if ((count1 = "1001") and (count2 = "0101")) then
count1 <= "0000";
count2 <= "0000";
if carryOut = '0' then
carryOut <= '1';
else
carryOut <= '0';
end if;
elsif count1 = "1001" then
count1 <= "0000";
count2 <= count2 + 1;
else
count1 <= count1 + 1;
end if;
-- What to do when counting down (This logic is hard to understand)
else
if ((count1 = "0000") and (count2 = "0000")) then
count1 <= "1001";
count2 <= "0101";
if carryOut = '0' then
carryOut <= '1';
else
carryOut <= '0';
end if;
elsif count1 = "0000" then
count1 <= "1001";
count2 <= count2 - 1;
else
count1 <= count1 - 1;
end if;
end if;
-- When counting is disabled, but there is an active edge (do nothing)
else
count1 <= count1;
count2 <= count2;
end if;
-- Code to run when entering values (will not be run if counting = '1') << Externally enforced
elsif rising_edge(digitUp1) then
if count1 = "1001" then
count1 <= "0000";
count1 <= count1 + 1;
else
count1 <= count1 + 1;
end if;
-- Code to run when entering values (will not be run if counting = '1') << Externally enforced
elsif rising_edge(digitUp2) then
if count2 = "0101" then
count2 <= "0000";
count2 <= count2 + 1;
else
count2 <= count2 + 1;
end if;
-- What to do when there is no active edge or other events (nothing)
else
count1 <= count1;
count2 <= count2;
end if;
end process;
-- Assign outputs
BCD1 <= count1;
BCD2 <= count2;
clockOut <= carryOut;
end structure;