VHDL:从INTEGER类型转换为STD_LOGIC_VECTOR


28

我构建了一个mod-16计数器,输出结果是INTEGER(我看到的所有示例都使用INTEGER)。

我构建了一个十六进制至7段显示的解码器,它的输入是STD_LOGIC_VECTOR(用这种方式编写,因为它很容易映射出真值表)。

我想将计数器的输出连接到解码器的输入,但是尝试在QuartusII中编译时出现“类型不匹配”错误。

有没有一种方法可以将VHDL列表中的INTEGER类型转换为STD_LOGIC_VECTOR类型?

Answers:


20

正如其他人所说,use ieee.numeric_std,never ieee.std_logic_unsigned,实际上不是IEEE软件包。

但是,如果您使用支持VHDL 2008的工具,则可以使用新程序包ieee.numeric_std_unsigned,该程序包的std_logic_vector行为本质上类似于未签名。

另外,由于我没有看到它明确说明的内容,因此这里是将(无符号)整数转换为的实际代码示例std_logic_vector

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

16

正如LoneTech所说,use ieee.numeric_std是您的朋友。您可以将a转换std_logic_vectorinteger,但必须将其强制转换为signedunsigned首先转换(因为编译器不知道您的意思)。VHDL是一种强类型语言。我已经在我的博客上写了更多有关此主题的文章

从根本上讲,我将您的7seg转换器更改为采用integer(或实际上为natural,因为它只处理正数)-则该转换就是一个简单的数组查找。设置一个包含转换的常量数组,然后使用在实体上用作输入的整数对其进行索引。


谢谢你 非常感谢您的评论。我当时担任过TA的职位,学习了VHDL以帮助对编程概念有点动摇的教授入门。我将把您的信息传递给他-我们使用的教科书并未深入探讨VHDL的“道德”问题。
J. Polfer,2010年

1
它不是一个“道德”问题,而是它保证了一致性。numeric_std库是IEEE制定的真实标准,而std_logic_unsigned库是由供应商组成的,并在行业中采用而没有任何实际的正式定义。尽管通常可以正常工作,但不能保证与非标准库的跨供应商兼容性。不过,现在是继续采用标准的好形式。
MattG 2011年

1

假设您的4位计数器有一个INTEGER输出SOME_INTEGER,并且您想将其转换为4位STD_LOGIC_VECTOR

SOME_VECTOR <= conv_std_logic_vector(SOME_INTEGER, 4);

您还可以使用它来初始化具有有意义数字的向量

SOME_VECTOR <= conv_std_logic_vector(9, 4); -- instead of "1001"

我认为您可能需要添加“使用IEEE.STD_LOGIC_ARITH.ALL;”。和/或STD_LOGIC_UNSIGNED。

互补运算为conv_integer(vector)。在进行比较时,我喜欢使用它。所以我可以声明

constant SOME_CONSTANT : integer := 999;

然后,稍后,我可以在if语句中使用它

if (conv_integer(SOME_VECTOR)=SOME_CONSTANT)
  then OTHER_VECTOR <= (others => '0');
end if;

编辑:您不需要将变量声明为Integer。尝试将声明更改为std_logic_vector。+和-运算符适用于std_logic_vectors。


3
请不要这样做!使用numeric_std(请参阅LoneTech和我的回答)
Martin Thompson 2010年

如果您有更好的方法,那很好,但是我的建议可行,因此我认为您的否决票是不必要的。我已经使用std_logic_arith多年了,但是我从来没有遇到任何问题。我认为对供应商更改其实现方式的担心是没有根据的;哪位供应商正确地考虑会破坏其客户的设计?
ajs410 2010年

1
您已经对什么供应商会故意将特定于供应商的东西放入IEEE名称空间的问题有了答案。它仍然很粗糙,尤其是在处理带符号无符号值时。
Yann Vernier 2010年

“ +和-运算符适用于std_logic_vectors。” AFAIK,它们不起作用,除非我误解了您的意思。通常必须先强制​​转换为保留签名/未签名数据的类型。
斯坦里


0

正如主要答案所说,推荐的方法如下:

use ieee.numeric_std.all;
...
my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

但是,我想详细说明为什么建议这样做,以及为什么VHDL具有将整数转换为std_logic_vectors的看似复杂的方式。

这取决于工具如何查看这些类型。

standard_logic_vector实际上是一堆1或0。我有10001。这是什么数字?这得看情况。它是签名的还是未签名的?SLV不知道或不在乎。多少位?好吧,您的SLV多长时间?

一个整数是有符号的,通常为32位(如果我没记错的话)。

阶段1:使我的整数更短且无符号。这就是这一部分:

to_unsigned(my_int, my_slv'length));

“我有这个整数,我希望它是无符号的,并且我希望它适合我的SLV的长度。”

第2阶段:然后,获取这些位并将其用于驱动my_slv。

my_slv <= std_logic_vector(...)

“获取这些位,并使用它们来驱动我的slv”

A <= B由于“ A由B驱动”,VHDL中的术语说明被大声读出。)

结合起来,这将使您:

my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));

当来自传统编程背景时,很容易陷入编程思维中。但是在VHDL中,您编写的代码对硬件有物理影响。知道这种方法为何有效并被推荐,这比从硬件方面考虑要写的内容还要近一步。

温馨提示:以to_为前缀的函数是可以缩短/更改操作数的函数。它们使它们无符号或一定长度或两者兼而有之。这就是为什么to_unsigned需要您指定长度。当类型已经直接兼容时,使用不带to_的函数(在此示例中为std_logic_vector(...)直接)。“将这些位取为此类,无需修改”。这些没有长度参数,因为双方已经相同。因此,在构建类似这样的东西时,我不需要查找它,只需要考虑如何更改数据即可。


0

要将整数转换为std_logic_vector,您有几种选择。使用numeric_std:

vect <= std_logic_vector( to_unsigned( your_int, vect'length));

要么

vect <= std_logic_vector( to_signed( your_int, vect'length));

使用std_logic_arith:

vect <= conv_std_logic_vector( your_int, vect'length);

std_logic_arith不是一个ieee标准,但是大多数工具将其编译到IEEE库中,并且被广泛使用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.