无法确定 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;
我目前正处于 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;