如何在 VHDL 中检查 "ZZZZ" 输入?

How to check for "ZZZZ" input in VHDL?

我有一个 in std_logic_vector(3 downto 0) 和一个 out std_logic_vector(6 downto 0)。有了流程和案例,我正在检查所有可能的二进制条件,例如 when "0000" => output_var <= "1111111"; 等等。我的程序适用于所有指定的二进制组合输入到模拟输出。

我在以下情况下添加了这一行:when "ZZZZ" => output_var <= "0000000"; 但这行不通,在模拟(quartus)中当输入为 "ZZZZ" 时输出未定义。我可能做错了什么,不允许检查 "ZZZZ" 吗?

编辑 1:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity my_entity is
    port(
        input_var : in std_logic_vector(3 downto 0);
        output_var : out std_logic_vector(3 downto 0));
end my_entity;

architecture arch of my_entity is
begin
    process(input_var) begin
        case input_var is
            when "0000" => output_var <= "1011110";
            when "0001" => output_var <= "0100000";
            when "0010" => output_var <= "0101101"; -- and so on
            when "ZZZZ" => output_var <= "0000000"; -- ++
        end case;
    end process;
end arch; 

编辑 2:

最上面是4个输入,最下面:展开7个输出;波形模拟(编辑 3:与上面显示的代码不同,但为了演示 ZZZZ 时模拟显示的示例)

您用来验证设计的工具可能不是 VHDL 模拟器。更有可能的是,它是一个逻辑合成器,加上一个门级模拟器。它首先生成您设计的门级实现,然后对其进行仿真。

区分VHDL代码的仿真、VHDL代码的综合和综合结果的仿真很重要。

  1. 让我们从模拟开始

    std_logic是九值枚举类型('0''1''Z'是其中的3个,另外6个是'-''U''X''H''L''W')。因此,您的 4 位 std_logic_vector input_var 可以采用 9^4 = 6561 个不同的值。您的第一个代码无效,甚至不应该编译,因为您的 case 语句没有列出选择器的所有可能值。使用涵盖所有尚未列出的选项的特殊选项 others 是处理这种情况的优雅方式:

    process (input_var) 
    begin
      case input_var is
        when "0000" => output_var <= "1011110";
        when "0001" => output_var <= "0100000";
        when "0010" => output_var <= "0101101"; -- and so on
        when "ZZZZ" => output_var <= "0000000"; -- ++
        when others => output_var <= "0000000"; -- others
      end case;
    end process;
    

    With this error fixed, your code should compile, simulate and produce the exact results you are expecting: when the selector takes value "ZZZZ", the output should take value "0000000".对于模拟器来说,"ZZZZ"只是input_var的可能值之一,没有任何特殊意义,就像"1111""1010"一样。任何有效的模拟器(符合 VHDL 标准)的行为都是一样的。此代码有效。

  2. 合成

    逻辑综合是组装逻辑门(寄存器、and、or、xor、not...)以实现 VHDL 代码行为的过程。在那里,你遇到了一个问题,因为很难创建检测值 "ZZZZ" 的硬件,尤其是区分 'Z''H''L' 和 [=21] =],这是其他高阻抗值。即使类型限于 '0''1''Z'std_logic 不是这种情况),在硬件中检测高阻抗可能并非不可能但很困难。当您使用 Quartus 时,我猜您的目标是 Altera FPGA。 FPGA中没有这种高阻检测硬件

  3. Post-合成模拟

    模拟综合结果让我们回到模拟(计算机科学)世界。弱('Z''L''H''W')或未知('U''X''-')的处理值取决于工具。在大多数情况下,门级仿真器会突出显示这些值,因为除了极少数情况外,它们是不受欢迎的并且是设计或编码错误的结果。即使真实硬件不会,该工具也可能会选择通过传播这些值来过度夸大。这是一种警告您出现问题的方法(同样,除非在极少数情况下,您不希望数字硬件中出现这些值)。

反正你设计的是7段控制器。在 others 选择中处理所有非 '0''1' 的值,这也将涵盖您最后的有效配置。这应该在模拟、综合和 post-综合模拟中按预期工作。如果你真的想在你的输入之一不是 '0''1' 时收到警告,在 pre-synthesis 模拟期间,你可以添加一个不可综合的断言,类似于:

architecture arch of my_entity is

  function is_01(v: std_logic_vector) return boolean is
  begin
    for i in v'range loop
      if v(i) /= '0' and v(i) /= '1' then
        return false;
      end if;
    end loop;
    return true;
  end function is_01;

begin

-- pragma synthesis_off
  assert is_01(input_var) report "Invalid input" severity error; 
-- pragma synthesis_on

  process (input_var) 
  begin
    case input_var is
      when "0000" => output_var <= "1011110";
      when "0001" => output_var <= "0100000";
      when others => output_var <= "0101101"; -- others, including "0010"
    end case;
  end process;

end architecture arch;