1

我正在尝试验证四个按钮。当其中一个被推动时,我需要检查相应的 LED 是否亮起。所以,我做了代码,其中一个进程检查哪个按钮被按下,并将值与 LED 的值(亮与否)进行比较。当我想增加控制玩家命中(成功)数量的变量时,就会出现问题。

记住“acertos”是std_logic_vector(3 downto 0) 类型的信号

process(pb0,pb1,pb2,pb3)
    variable erro_int   : STD_LOGIC;
begin
    if (clk_game = '0') then
        erro_int:='0';
        if rising_edge(pb0) then
            if pb0 /= led(0) then 
                erro_int:='1';
            end if;
        elsif rising_edge(pb1) then
            if pb1 /= led(1) then 
                erro_int:='1';
            end if;
        elsif rising_edge(pb2) then
            if pb2 /= led(2) then 
                erro_int:='1'; 
            end if;
        elsif rising_edge(pb3) then
            if pb3 /= led(3) then 
                erro_int:='1'; 
            end if;
        else    
            acertos <= acertos+1;
        end if;
    end if;
end process;
4

1 回答 1

0

请参阅错误 (10818): Can't infer register for "E" at clk200Hz.vhd(29) 因为它没有在时钟沿之外保持其值,这证明了完全相同的错误情况。通常,您也会被鼓励将供应商用作错误消息的资源。

这里的错误情况是表示acertos赋值没有发生在依赖于用作时钟的信号事件的条件赋值语句内。

然而,这并不是您在某些设计规范中向我们展示的过程中可能遇到的潜在问题的终结。

存在信号pb0pb1和是否被pb2pb3抖动过滤的问题。请参阅Wentworth Institute of Technology Department of Electronics and Mechanical ELEC 236 Logic Circuits Switch Debounce Design,其中第一个示波器轨迹显示了一个通常拉高的瞬时开关连接到接地开关输入。问题是接触反弹。该网页讨论了一些解决方案。

De-bounce 将允许您将按钮输入用作时钟,但您的过程中还有其他问题。

例如,一些供应商不会在同一个过程语句中接受多个时钟,您的设计规范可能不具有可移植性。

没有公认的顺序事件推断存储元素构造允许同一存储元素使用多个时钟 ( erro_int)。因为没有相互依赖的连续 if 语句表示模拟时间的流逝,您可能会期望可能只有最后一个语句表示为硬件。

您可以将所有按钮组合成一个信号:

button_press <= not (not pb0 and not pb1 and not pb2 and not bp3);

从未按下任何按钮转换时,按下任何按钮都可能导致边缘事件。

如果您使用计数器来消除抖动并测试连续事件,您可以将其用作唯一的时钟。

让我们假设它是去弹跳的。在流程语句中设置默认值erro_out将为您提供一个类似于以下内容的流程:

process(button_press)
    variable erro_int: std_logic;
begin
    if (clk_game = '0') then
        erro_int:='0';
        if rising_edge(button_press) then
            if pb0 /= led(0)  or pb1 /= led(1) or pb1 /= led(2) or pb3 /=pb3 then 
                erro_int:= '1';
            end if;
        acertos <= acertos + 1;
    end if;
end process;

(我查了 acertos 的翻译——命中,不一定是有效命中,我认为这是一个游戏。)

这仍然不能解决erro_int局部变量的问题。如果它在其他地方使用,它希望被声明为信号。如果您将流程更改为:

...
signal erro_int:   std_logic;  -- defined say as an architecture declarative item
...

process(button_press)
begin
    if (clk_game = '0') then
        erro_int <='0';
        if rising_edge(button_press) then
            if pb0 /= led(0)  or pb1 /= led(1) or pb1 /= led(2) or pb3 /=pb3 then 
                erro_int <= '1';
            end if;
        acertos <= acertos + 1;
    end if;
end process;

您可以在外部使用它。这样做的原因是一个进程只有一个信号驱动程序,并且当前仿真时间的最后一个分配是生效的(当前仿真时间只有一个分配)。

当然,如果您使用时钟去抖动,button_press如果它被选通到仅持续一个时钟,您可以将其用作启用。

于 2014-07-25T01:47:54.953 回答