I am trying to make a VHDL code in Quartus that turns on buzzer when I push button1 on the demo board and turns it off when I push button 2. But, it doesn't react to button2. It compiles without errors, but doesn't work as I expected. It always produces sound.
How do I make it to turn on when I push button1 and turn off when I push button2?
architecture Behavioral of buzz is
signal Hz_counter : natural range 0 to 56818 := 0;
signal wave : std_logic := '0';
signal sound_on : std_logic := '0';
signal sound_off : std_logic := '0';
begin
process(clk, button1, button2)
begin
if rising_edge(clk) then
Hz_counter <= Hz_counter + 1;
if Hz_counter >= 56818 then
wave <= not wave;
Hz_counter <= 0;
end if;
end if;
if rising_edge(button1) then
sound_on <= '1';
end if;
if rising_edge(button2) then
sound_off <= '1';
end if;
if (sound_on = '1') then
sound_off <= '0';
end if;
if (sound_off = '1') then
sound_on <= '0';
end if;
end process;
buzzer <= wave when (sound_on = '1') else '0';
end Behavioral;
You have built two flip-flops that are set by the rising edges of buttons, but asynchronously reset by the set state of each other.
Initially, sound_on
and sound_off
are '0'.
If you press button1
, sound_on
becomes '1'. This keeps sound_off
at '0' asynchronously:
if (sound_on = '1') then
sound_off <= '0';
end if;
If you want to observe the same effect but for button2
, press it as the first button. Now you are not able to switch the sound on with button1
.
The solution is to avoid this kind of dead-lock. Use only one flip-flop to store "sound on/off".
The most simple alternative is to use button1
to set and button2
to reset:
if button1 = '1' then
sound_on <= '1';
elsif button2 = '1' then
sound_on <= '0';
end if;
If you want a clocked flip-flop, use button1
as clock to set and button2
as reset. Since the asynchronous signal has higher priority in the real world, you need write this:
if button2 = '1' then
sound_on <= '0';
elsif rising_edge(button1) then
sound_on <= '1';
end if;
Finally, a pure synchronous design is:
if rising_edge(clk) then
if button1 = '1' then
sound_on <= '1';
elsif button2 = '1' then
sound_on <= '0';
end if;
end if;