无法确定 VHDL 中的信号值

Unable to determine signal value in VHDL

我目前正处于 12 小时的调试过程中,我这辈子都无法度过这个难关。

我的代码设置方式,我有一个 8 位 std_logic_vector 映射到 DE2-115 板上的 8 个开关。每个位对应于相关开关(0或1)激活的逻辑电平。

目标是让电路板在启动计时器之前等待 8 个开关中的任何一个被激活。这将在信号 relative_time_enable 设置为逻辑状态 1 时激活。一旦信号设置为 1,它最终将永远不会重置回 0。该变量初始化如下所示:

signal relative_time_enable          : STD_LOGIC := '0';
signal signal_in                     : STD_LOGIC_VECTOR(7 downto 0);

signal_in 被映射到我实体中声明的 'in' 端口,反之亦然。然而据说, signal_in 对应于开关。这是我现在拥有的代码。

process(clk_1MHz_enable, signal_in)     
begin
    if(clk_1MHz_enable = '1') then

            if(relative_time_enable = '0') and (signal_in /= "00000000")then
                    relative_time_enable <= '1';
            end if;
    end if;
end process;

我相信我已经将问题归结为 if 语句总是出现为真。几乎就像 signal_in 在第一个周期内经历多个状态导致值立即设置为 1,我在网上找不到任何可以指向正确方向的东西。

此时,我已经尝试了一切以确定实际值是什么,包括将“00000000”替换为“11111111”、"UUUUUUUU"、"ZZZZZZZZ"、"XXXXXXXX" 和他们都仍然通过。

我也试过:

process(clk_1MHz_enable, signal_in)     
begin
    if(clk_1MHz_enable = '1') then

            if(relative_time_enable = '0') and (signal_in /= "00000000")then

                    for i in 0 to 7 loop
                            if(signal_in(i) = '1') then
                                    relative_time_enable <= '1';
                            end if;
                    end loop;

            end if;
    end if;
end process;

这个方法看起来应该 'double check' 但不知何故它一直通过并在任何开关被激活之前将值设置为 1。另外,我在 lCD 上显示 signal_in,当我移动开关和启动时,一切都显示为 00000000。

仅供参考:我只用这个 FPGA 和 VHDL 工作了 2 周,所以我很可能遗漏了一些非常基本的东西。此外,我对自己在 ModelSIM 中的技能并不是 100% 有信心,也不确定如何将我看到的转化为代码问题。

如有任何帮助,我们将不胜感激。如果您需要查看更多代码,请告诉我,我很乐意 post 提供任何需要的信息。我只是没有把所有的都放上去,因为有一个相当长的状态机控制着与这个无关的 LCD post。

此外,我应该提到以下代码按预期工作,但此代码的问题在于它将 relative_time_enable 重置回 0,这是一个很大的禁忌。我展示这个的唯一原因是因为它实际上确实在启动时钟之前等到开关处于活动状态,但是一旦我停用开关,时钟就会停止运行,这是一个问题。

process(clk_1MHz_enable, signal_in)     
begin
    if(clk_1MHz_enable = '1') then

            if(relative_time_enable = '0') and (signal_in /= "00000000")then
                    relative_time_enable <= '1';
            else
                    relative_time_enable <= '0';
            end if;
    end if;
end process;

您的测试将使用 bit_vector,因为每个位都将采用 '0' 值或 '1' 值。所以,/= "00000000" 的真正意思是:至少有一位是 '1'。但是当您使用 std_logic_vector 时,每个位可以取 9 个不同的值(std_logic 是一个 9 值枚举类型)。所以/= "00000000"并不代表至少有一位是'1'。这可能意味着一位被设置为 'U' 或不同于 '0' 的任何其他值。在模拟开始时,signal_in 被初始化为 "UUUUUUUU"(U 代表 未初始化)。relative_time_enable 被初始化为 '0' 因为你是这样声明的。所以你的测试在 clk_1MHz_enable 的第一个上升沿通过,relative_time_enable 几乎立即卡在 '1'

假设clk_1MHz_enable是一个时钟(奇怪的名字但为什么不是),而你想要一个边沿触发的D触发器,下面的代码解决了这个问题:

process(clk_1MHz_enable)     
begin
  if clk_1MHz_enable = '1' and clk_1MHz_enable'event then
    for i in signal_in'range loop
      if signal_in(i) = '1' then
        relative_time_enable <= '1';
      end if;
    end loop;
  end if;
end process;

如果您想要电平触发锁存器而不是边沿触发 D 触发器:

process(clk_1MHz_enable, signal_in)
begin
  if clk_1MHz_enable = '1' then
    for in in signal_in'range loop
      if signal_in(i) = '1' then
        relative_time_enable <= '1';
      end if;
    end loop;
  end if;
end process;