首页 文章

仅使用std_logic_vector包将std_logic_vector与常量进行比较

提问于
浏览
3

我只在我的VHDL文件中使用以下包:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

在代码中,我比较了一个std_logic_vector信号:A和一个常数值,例如

...if A<="00001011" then

但Xilinx ISE正确检查了代码 . 我的理解是STD_LOGIC_1164包不包含具有作为操作数std_logic_vector的不等式的实现,那么为什么上面的代码语句被接受并且上述比较是否将A视为有符号或无符号数?

4 回答

  • 2
    • 复制我的comp.lang.vhdl回复此帖子 . 对不起有些重复,但有些没有 .

    所有枚举类型和枚举类型数组都隐式定义了常规排序关系运算符(>,> =,<,<=) . 不幸的是,它没有数字排序,因此结果可能不如预期 . 相反,它是字典排序 .

    首先,您必须查看元素类型,即std_logic,其基类型为std_ulogic . 对于枚举类型,例如std_ulogic,左值小于正确值,因此,对于std_ulogic(和std_logic):'U'<'X'<'0'<'1'<'Z'<'W'< 'L'<'H'<' - '

    对于其元素基类型为std_ulogic的等长数组(例如std_logic_vector或std_ulogic_vector),其值仅为0或1,事情很好:“1010”>“0101”

    请注意,字典比较始终首先比较左元素 . 因此,对于字符串,以“S”开头的东西总是小于以“T”开头且与长度无关的东西 . 这非常适合将字符串排序到字典中,并且是唯一的实际默认值 - 如果我们要提供诸如事物之类的话 .

    OTOH,如果你认为事物是数字的,那就没那么好了 . 例如,如果数组的长度不相等,则以下情况为真,因为左侧参数的前导'1'>右参数的前导'0' .
    "100"> "0111"

    因此,仅使用“使用ieee.std_logic_1164.all”,您可能会错误地将std_logic_vector视为数字(例如unsigned) .

    许多人会说,从不使用std_logic_vector进行数学运算,而“>”则是数学运算 . 我普遍同意 .

    那我该怎么办?如何保护我的设计和设计团队 . 首先,您必须确定策略以及如何实施它 .

    1)禁止使用常规排序关系运算符(>,> =,<,<=)和std_logic_vector,并使用lint工具强制执行它 . 但是,这意味着您必须购买并要求使用棉绒工具 .

    2)禁止将常规排序关系运算符(>,> =,<,<=)与std_logic_vector一起使用,并使用以下两个包引用强制执行它 . 请注意,这会通过引用每个运算符的两个定义来生成错误,因此,在使用时,表达式变得不明确 . 请注意,这可能会有问题,因为在1076-2008中引入了numeric_std_unsigned,并且您的综合工具可能还不支持它 .
    图书馆;使用ieee.numeric_std_unsigned.all;使用ieee.std_logic_unsigned.all;

    3)放松一些规则 . 我们最关心的是设计的正确性 . 允许将std_logic_vector解释为无符号值,并引用numeric_std_unsigned(首选,但它是VHDL-2008,可能尚未由您的综合工具实现 - 但如果不确定提交错误报告)或std_logic_unsigned(不是首选 - 这是一个旧的共享软件包,它不是IEEE标准,也许不属于IEEE库 - OTOH,它得到了很好的支持,并且与其他软件包(例如numeric_std)一起使用很好 .

    这样做的好结果是它还允许包含整数的比较:如果A <= 11那么

    注意,有些人认为在numeric_std_unsigned / std_logic_unsigned中重载“>”和朋友是非法的 . 这是对VHDL-2008之前的1076的非常保守的解释 . 它是针对VHDL的所有版本修复的,在VHDL-2008之前使用ISAC解决方案确定明确定义的运算符总是重载隐式定义的运算符而不会产生任何歧义 . 我注意到即使VHDL FAQ在这个问题上已经过时了 .

    4)要正式但实用 . 永远不要使用std_logic_vector . 仅使用数字类型,例如未签名和从包ieee.numeric_std签名 . 有符号和无符号的类型也支持与整数进行比较 .

    可能有一些我遗漏的策略 .

    请注意,VHDL-2008引入了匹配运算符,它们也解决了这个问题,没有为没有数字解释的类型定义它们 . 这些运算符是:?=,?/ =,?>,?> =,?<,?<=

  • 3

    “<=”在VHDL中称为关系运算符 .

    它是预定义的 . 参见IEEE Std 1076-2008,9.2.3关系运算符表 . 它是任何标量或单维离散阵列类型的预定义运算符 .

    std_logic_vector有资格作为单维离散数组类型,它的元素类型是离散的,在这种情况下是枚举类型(STD_LOGIC / std_ulogic) . 请参见5.2标量类型,5.2.1常规,其中第一段演示枚举类型是离散的 .

    而对于更简单的答案,它是语言的一部分 .

  • 2

    简短回答:您需要使用额外的包裹: ieee.numeric_std

    我必须假设你已经将A定义为 std_logic_vector(7 downto 0) .

    此数据类型表示位数组 . 没有与之关联的数值 . 因此,A和您的位字符串文字之间的比较没有意义 .

    如果要比较A表示的数值,则需要使用 unsigned(7 downto 0)signed(7 downto 0) ,最好使用 ieee.numeric_std 包 . 这是将数值赋值给位数组的公认良好做法 .

    从技术上讲,您可以解决此问题并定义自己的“<=”函数,但您只需复制VHDL标准IEEE库中的代码 .

  • 2

    扩展为离散数组预定义的David 's answer slightly: it',这样,基本上,数组元素从左到右进行比较(根据IEEE 1076-2008,9.2.3),并且每个标量数组元素使用其固有顺序进行比较,其中,像 std_logic 这样的枚举的情况是由它的位置定义的(根据5.2.2.1) . '1' 是"greater than" '0' 只是因为它在 std_ulogic 声明中的位置更高(并且出于同样的原因 'Z' 是"greater than" '1' ) .

    由此可以清楚地看出,它并没有将向量视为有符号或无符号 . 碰巧看起来它正在将向量视为无符号 if 它们等长 and 只包含 '0''1' ,但你仍然不应该这样做 .

相关问题