我正在查看this example及以下答案,这是一个很好的解决方案,可以产生两个补码:
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位减法器”。代码如下所示:
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;
但是,我收到一条错误消息: 错误:附近的类型错误;当前类型std_logic_vector;预期类型未签名。
请帮我解决这个问题。
答案 0 :(得分:1)
由于没有人回答这个问题而没有人投票,我会回答。
查看错误
错误:附近的类型错误;当前类型std_logic_vector;期望的类型无符号。
现在看一下实体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
!就像错误一样。
std_logic_vector
和unsigned
是两种不同的类型。由于VHDL是一种强类型语言,因此您不能将数据从一种类型放到另一种类型。您需要使用类型转换。
对于不相关的类型,您应该实现类型转换功能。或函数,如果您想要双向转换。 E.g。
function (input : type_a) return type_b;
但在这种情况下,std_logic_vector
和unsigned
具有相同的基础类型std_logic
。 (std_ulogic
实际上自VHDL-2008以来我相信。)
在这种情况下,您可以显式转换为一种类型。 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.但在Behavioral
的{{1}}架构中,您可以使用16位进行提供,而不更改通用值。这不起作用。
另外:subtractor_16bit
有两个端口:twoscomplement
和A
。但是在Y
中,您开始使用subtractor_16bit
和A
。这是一个糟糕的编码实践。
最后,您可以删除C
声明。只需从库中实例化实体。 E.g。
component
所以,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
,端口NBits
的大小为Y
1 即可。那是因为你似乎想要保持16位的值精度。因此,在将unsigned转换为signed时,需要为符号添加第17位。因此,您需要修改其余的代码!
....但这可以用不同的方式修复。我会向你学习两个补充:NBits
。
证明(采用4位有符号精度):
-a = not(a) + 1
= not(b'0000)+1
= b'1111'+1
b'0000'
= not(b'0111)+1
= b'1000'+1
b'1001'
= not(b'1010)+1
= b'0101'+1
请参阅?
所以现在我将为您解决难题:
b'0110'
您仍需要更改/修复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
行为......