我正在尝试在 Quartus 中编写一个 VHDL 代码,当我按下 demobord 上的按钮 1 时,它会打开蜂鸣器;当我按下按钮 2 时,它会关闭蜂鸣器。但它对按钮 2 没有反应。它编译没有错误,但没有按照我的预期工作。它总是发出声音。如何让它在按下按钮1时打开并在按下按钮2时关闭?
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;
您已经构建了两个触发器,它们由按钮的上升沿设置,但由彼此的设置状态异步复位。
最初,
sound_on
和 sound_off
为“0”。
如果按
button1
,sound_on
会变为“1”。这使 sound_off
异步保持为“0”:
if (sound_on = '1') then
sound_off <= '0';
end if;
如果您想观察相同的效果,但对于
button2
,请按第一个按钮。现在您无法使用 button1
打开声音。
解决办法就是避免这种死锁。仅使用一个触发器来存储“声音开/关”。
最简单的替代方法是使用
button1
进行设置并使用 button2
进行重置:
if button1 = '1' then
sound_on <= '1';
elsif button2 = '1' then
sound_on <= '0';
end if;
如果您想要时钟触发器,请使用
button1
作为时钟进行设置,使用 button2
作为复位。由于异步信号在现实世界中具有更高的优先级,因此您需要这样写:
if button2 = '1' then
sound_on <= '0';
elsif rising_edge(button1) then
sound_on <= '1';
end if;
最后一个纯同步设计是:
if rising_edge(clk) then
if button1 = '1' then
sound_on <= '1';
elsif button2 = '1' then
sound_on <= '0';
end if;
end if;