VHDL 类型转换签名为 std_logic_vector [英] VHDL typecast signed to std_logic_vector
问题描述
我正在查看 这个例子 和下面的答案,这是产生二进制补码的一个很好的解决方案:
I am looking at this example and below answer which is a nice solution to produce two's complement:
library ieee;
use ieee.numeric_std.all;
entity twoscomplement is
generic
(
Nbits : positive := 8
);
port
(
A : in unsigned (Nbits-1 downto 0);
Y : out signed (Nbits downto 0)
);
end entity twoscomplement;
architecture a1 of twoscomplement is
begin
Y <= -signed(resize(A, Y'length));
end architecture;
我想使用上述示例进行补码,然后制作16 位减法器".代码如下所示:
I want to use the said example to have two's complement and then make a "16-bit subtractor". The code will look like the following:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity subtractor_16bit is
Port ( a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
cin : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end subtractor_16bit;
architecture Behavioral of subtractor_16bit is
component fulladder_16bit is
Port (
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
cin : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end component;
component twoscomplement is
Port (
A : in unsigned (15 downto 0);
C : out signed (15 downto 0)
);
end component;
signal n1 : STD_LOGIC_VECTOR(15 downto 0);
begin
twoscomplement_1: twoscomplement port map (a => a ,c => n1); --ERROR
fulladder_16bit_1: fulladder_16bit port map (a => a, b => n1, sum => sum , cin => cin, cout => cout, over => over);
end Behavioral;
但是,我收到一条错误消息:错误:在 a 附近输入错误;当前类型 std_logic_vector;预期类型为无符号.
However, I am receiving an error saying: Error: type error near a; current type std_logic_vector; expected type unsigned.
请帮我解决这个问题.
推荐答案
既然没有人回答这个问题,也没有人反对,我来回答.
As nobody is answering this and nobody is down voting it, I will answer.
看错误
错误:在 a 附近输入错误;当前类型 std_logic_vector;预期类型为无符号.
Error: type error near a; current type std_logic_vector; expected type unsigned.
现在看实体subtractor_16bit
.
[...]
entity subtractor_16bit is
Port ( a : in STD_LOGIC_VECTOR(15 downto 0);
[...]
component twoscomplement is
Port (
A : in unsigned (15 downto 0);
[...]
twoscomplement_1: twoscomplement port map (a => a ,c => n1);
[...]
你看到了什么?twoscomplement
需要 unsigned
,而 a
是 std_logic_vector
! 就像错误所说.
What do you see? twoscomplement
expects an unsigned
, while a
is std_logic_vector
! Just like the error says.
std_logic_vector
和 unsigned
是两种不同的类型.由于 VHDL 是一种强类型语言,您不能只是将数据从一种类型转换为另一种类型.您需要使用类型转换.
std_logic_vector
and unsigned
are two separate types. As VHDL is a strongly typed language, you cannot just put the data from one type to another. You need to use type conversion.
对于不相关的类型,你应该实现一个类型转换函数.或者函数,如果你想要双向转换.例如
For unrelated types, you should implement a type conversion function. Or functions, if you want bidirectional conversion. E.g.
function (input : type_a) return type_b;
但在这种情况下,std_logic_vector
和 unsigned
具有相同的底层类型,std_logic
.(std_ulogic
实际上自 VHDL-2008 以来我相信.)在这种情况下,您可以明确地从一种类型转换为另一种类型.例如
But in this case, std_logic_vector
and unsigned
have the same underlying type, std_logic
. (std_ulogic
actually since VHDL-2008 I believe.)
In that case you can convert from one type to another explicitly. E.g.
signal a_u : unsigned(y downto 0);
signal a_slv : std_logic_vector(y downto 0);
begin
a_u <= unsigned(a_slv);
接下来,您没有正确实例化 twoscomplement
组件.实体有一个通用的Nbits
.默认情况下,您将其设置为 8.但是在 subtractor_16bit
的架构 Behavioral
中,您将其提供给 16 位,而不更改通用值.那不行.
Next, your not instantiating the twoscomplement
component properly. The entity has a generic Nbits
. By default you set it to 8. But in your architecture Behavioral
of subtractor_16bit
, you feed it with 16 bits, without changing the generic value. That doesn't work.
另外:twoscomplement
有两个端口:A
和 Y
.但是在 subtractor_16bit
中,您开始使用 A
和 C
.这是糟糕的编码习惯.
Also: twoscomplement
has two ports: A
and Y
. But in subtractor_16bit
you start using A
and C
. That's bad coding practice.
最后,您可以删除 component
声明.只需从库中实例化实体.例如
Finally, you can drop the component
declarations. Just instantiate the entities from the library. E.g.
twoscomplement_1: entity work.twoscomplement [...]
所以,subtractor_16bit
应该是这样的:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity subtractor_16bit is
Port (
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
cin : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end entity;
architecture structural of subtractor_16bit is
use IEEE.NUMERIC_STD.ALL;
signal n1 : signed(a'range);
begin
twoscomplement_1: entity work.twoscomplement
generic map(
NBits => a'length
)
port map (
a => unsigned(a),
y => n1
);
fulladder_16bit_1: entity work.fulladder_16bit
port map (
a => a,
b => std_logic_vector(n1),
sum => sum,
cin => cin,
cout => cout,
over => over
);
end architecture;
...
正如您在实体 twoscomplement
上看到的那样,端口 A
的大小为 NBit
,端口Y
大小为 NBit
+1.那是因为您似乎想要保持 16 位值精度.所以在将无符号转换为有符号时,需要为符号添加第 17 位.因此,您的其余代码将需要修改!
As you see on your entity twoscomplement
, port A
has a size of NBits
, and port Y
has a size of NBits
+1. That is because you seem to want to keep 16-bit value precision. So when converting unsigned to signed, you need to add a 17th bit for the sign. As a result, the rest of you code will need to be modified!
.... 但这可以通过不同的方式修复.我会教你一些关于二进制补码的知识:-a = not(a) + 1
.
.... But this can be fixed a different way. I will learn you something about two's complement: -a = not(a) + 1
.
证明(采用 4 位有符号精度):
Proof (Take 4 bits signed precision):
- 0 = b'0000 =>-0 是
not(b'0000)+1
=b'1111'+1
=b'0000'
- 7 = b'0111 =>-7 是
not(b'0111)+1
=b'1000'+1
=b'1001'
- -6 = b'1010' =>6 是
not(b'1010)+1
=b'0101'+1
=b'0110'
- 0 = b'0000 => -0 is
not(b'0000)+1
=b'1111'+1
=b'0000'
- 7 = b'0111 => -7 is
not(b'0111)+1
=b'1000'+1
=b'1001'
- -6 = b'1010' => 6 is
not(b'1010)+1
=b'0101'+1
=b'0110'
看到了吗?
那么现在我来为你解开谜题:
So now I will solve your puzzle for you:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity subtractor_16bit is
Port (
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end entity;
architecture structural of subtractor_16bit is
begin
fulladder_16bit_1: entity work.fulladder_16bit
port map (
a => a,
b => not(b),
sum => sum,
cin => '1',
cout => cout,
over => over
);
end architecture;
您仍然需要更改/修复 cout
和 over
行为...
You will still need to change/fix the cout
and over
behavior...
这篇关于VHDL 类型转换签名为 std_logic_vector的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!