Vhdl 错误(10818):无法推断。。。在因为它的值不在时钟边缘之外

Vhdl 错误(10818):无法推断。。。在因为它的值不在时钟边缘之外,vhdl,quartus,Vhdl,Quartus,我正在尝试验证四个按钮。当按下其中一个按钮时,我需要检查相应的led是否点亮。因此,我编写了代码,其中一个过程检查按下了哪个按钮,并将值与led是否点亮的值进行比较。当我想增加控制玩家成功点击量的变量时,问题就出现了 记住acertos是一个std_logic_vector3类型的信号,一直到0 process(pb0,pb1,pb2,pb3) variable erro_int : STD_LOGIC; begin if (clk_game = '0') then

我正在尝试验证四个按钮。当按下其中一个按钮时,我需要检查相应的led是否点亮。因此,我编写了代码,其中一个过程检查按下了哪个按钮,并将值与led是否点亮的值进行比较。当我想增加控制玩家成功点击量的变量时,问题就出现了

记住acertos是一个std_logic_vector3类型的信号,一直到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;
查看哪一个演示了完全相同的错误情况。通常情况下,也会鼓励您使用供应商作为错误消息的资源

这里的错误案例表示acertos赋值不是在依赖于用作时钟的信号事件的条件赋值语句中进行的

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

问题在于信号pb0、pb1、pb2和pb3是否经过反弹跳滤波。请参阅,其中第一个示波器轨迹显示连接至接地开关输入的正常拉高瞬时开关。问题是接触反弹。该网页讨论了一些解决方案

反弹跳允许您将按钮输入用作时钟,但在您的过程中还有其他问题

例如,一些供应商不接受同一流程声明中的多个时钟,您的设计规范可能不可移植

不存在可识别的顺序事件推断存储元素结构,该结构允许对同一存储元素错误使用多个时钟。因为没有相互依赖性的连续if语句表示的模拟时间不会流逝,因此您可能会认为可能只有最后一个get被表示为硬件

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

button_press <= not (not pb0 and not pb1 and not pb2 and not bp3);
我查了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;
您可以在外部使用它。之所以这样做,是因为一个进程对一个信号只有一个驱动程序,而当前模拟时间的最后一个分配就是生效的分配。当前模拟时间只有一个分配


当然,如果你用一个时钟去反弹,如果它被选通到最后一个时钟,你可以使用按钮作为启用。

谢谢David。。。我试试看。
...
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;