如何在 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代码的综合和综合结果的仿真很重要。
让我们从模拟开始
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 标准)的行为都是一样的。此代码有效。
合成
逻辑综合是组装逻辑门(寄存器、and、or、xor、not...)以实现 VHDL 代码行为的过程。在那里,你遇到了一个问题,因为很难创建检测值 "ZZZZ"
的硬件,尤其是区分 'Z'
与 'H'
、'L'
和 [=21] =],这是其他高阻抗值。即使类型限于 '0'
、'1'
和 'Z'
(std_logic
不是这种情况),在硬件中检测高阻抗可能并非不可能但很困难。当您使用 Quartus 时,我猜您的目标是 Altera FPGA。 FPGA中没有这种高阻检测硬件
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;
我有一个 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代码的综合和综合结果的仿真很重要。
让我们从模拟开始
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 标准)的行为都是一样的。此代码有效。合成
逻辑综合是组装逻辑门(寄存器、and、or、xor、not...)以实现 VHDL 代码行为的过程。在那里,你遇到了一个问题,因为很难创建检测值
"ZZZZ"
的硬件,尤其是区分'Z'
与'H'
、'L'
和 [=21] =],这是其他高阻抗值。即使类型限于'0'
、'1'
和'Z'
(std_logic
不是这种情况),在硬件中检测高阻抗可能并非不可能但很困难。当您使用 Quartus 时,我猜您的目标是 Altera FPGA。 FPGA中没有这种高阻检测硬件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;