2 的补码输入和使用 vhdl 库进行有符号输入
2's compliment input and using vhdl library for signed input
我的输入数据是2的补码,我设计的输入是有符号数,所有的运算都是用有符号数,我用的库ieee.numeric_std.all,但是当我做'+'时发生错误"found '0' definitions of operator "+",无法确定“+”的精确重载匹配定义。所以我将另一个库更改为另一个库 ieee.std_logic_arith.all ans 将添加操作作为一个组件,它可以工作。
当我使用 testbench 模拟我的代码时,发生错误:实体端口 xin 与组件端口的签名类型不匹配。
我认为这个错误与我的图书馆有关。
谁能帮帮我?
新
我不使用加法器作为组件,下面的代码有效
adder: process(clk)
begin
if (clk'event and clk = '1')then
if enable1='1' then
add1 <= (x0(7)&x0) + (x15(8)&x15);
add2 <= (x1(7)&x1) + (x14(8)&x14);
add3 <= (x2(7)&x2) + (x13(8)&x13);
add4 <= (x3(7)&x3) + (x12(8)&x12);
add5 <= (x4(7)&x4) + (x11(8)&x11);
add6 <= (x5(7)&x5) + (x10(8)&x10);
add7 <= (x6(7)&x6) + (x9(8)&x9);
add8 <= (x7(7)&x7) + (x8(8)&x8);
end if;
end if;
end process adder;
我的测试平台的库使用use ieee.numeric_std.all;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;
ENTITY tb_signedinput IS
END tb_signedinput;
ARCHITECTURE behavior OF tb_signedinput IS
-- Component Declaration
COMPONENT signedinput is
port( Clk : in std_logic;
reset : in std_logic;
enable1 : in std_logic;
Xin : in signed(7 downto 0);
Yout : out signed(19 downto 0)
);
END COMPONENT;
--Inputs
signal Clk : std_logic := '0';
signal reset : std_logic := '0';
signal Xin : signed(7 downto 0) := (others => '0');
signal enable1 : std_logic := '0';
--Outputs
signal Yout : signed(19 downto 0);
-- Array
constant MEMSIZE: integer :=99;
type testarray is array (MEMSIZE downto 0) of signed(7 DOWNTO 0);
signal testvectors: testarray;
shared variable vectornum,outnum: integer;
-- Clock period definitions
constant Clk_period : time := 10 ns;
BEGIN
-- Component Instantiation
uut: signedinput PORT MAP( Clk => Clk,
reset => reset,
Xin => Xin,
enable1 =>enable1,
Yout => Yout );
错误仍然存在:
Entity port xin does not match with type std_logic_vector of component port
Entity port yout does not match with type std_logic_vector of component port
因此,我再次将加法器更改为
add1 <= resize(x0,9) + x15;
语法良好但在测试台中出现同样的错误..
我的 ISE 类型或库类型有误吗?
谢谢!
您在 adder1
中的加法表达式无效,因为当 a1
和 a2
的范围是 7 到 0 时,您试图索引元素“8”。
假设你正在尝试签署扩展它看起来更像这样:
q <=(a1(7)&a1 + a2(7)&a2);
“+”运算符的优先级高于“&”,因此您尝试添加 a1 + a2(7)
即 signed + std_logic
。除了逻辑错误之外,numeric_std
中没有定义重载。
这个有效:
q <=(a1(7)&a1) + (a2(7)&a2);
但这不是使用 numeric_std
时实现符号扩展的规范方式。您只需要左侧项的大小与 q
相同。带符号的“+”运算符将负责自动扩展其右侧的符号。
q <= resize(a1, q'length) + a2; -- Sign extend a1 and add
这提供了更清晰的代码,说明它在做什么而不依赖于非标准 std_logic_arith
。
关于 xin
类型不匹配的实际错误在您的代码中并不明显。有可能您的旧版本 signedinput
在其端口上编译了不同的类型并且没有更新库。
凯文让它看起来很难,所以我想我会展示一些可以很好解释的东西:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity adder1 is
port (
a1: in signed (7 downto 0);
a2: in signed (7 downto 0);
clk: in std_logic;
enable1: in std_logic;
q: out signed (8 downto 0)
);
end entity;
architecture behavioral of adder1 is
begin
UNLABELLED:
process(clk)
begin
if clk'event and clk ='1' then
if enable1 = '1' then
q <= a1(7) & a1 + a2 ;
end if;
end if;
end process;
end architecture;
q
的分配看起来很简单,所以值得解释一下。
numeric_std 中的“+”表示有符号会扩展较短的操作数以匹配较长操作数的长度。
剩下的就是优先魔法
“+”和“&”优先级相同,即按从左到右的textual顺序求值,即用连接符进行符号扩展首先(参见 IEEE Std 1076-2008,9.2 运算符)。
“+”运算符将左操作数视为较长,并将右操作数与其长度相匹配(请参阅程序包 numeric_std“+”,用于 L、R:有符号)。它通过在找到两个操作数的长度的 MAX 之后对两个操作数使用带符号的 RESIZE 以及将元值转换为“X”来实现这一点。
如果右操作数也更长,则有效:
q <= a1 + (a2(7) & a2) ;
这里我们需要括号将连接运算符的结果关联为加法运算符的右操作数,因为这两个运算符的优先级相同,否则会按文本顺序遇到。
没有理由再次调用调整大小,它只是通过串联进行一位符号扩展,基于知道符号包含在二进制补码的左侧元素(位)中。
在 VHDL 标准中找不到术语规范。
就 Xin 而言,我同意 Kevin 的观点,可能需要重新分析某些内容,以便在同一个包中找到对 signed 的两个引用。
设计中使用的每个声明都是唯一的。如果说端口映射中的实际依赖包 std_logic_arith 中的类型签名声明,而正式依赖包 numeric_std 中签名的声明,它们将是不同的类型。
我的输入数据是2的补码,我设计的输入是有符号数,所有的运算都是用有符号数,我用的库ieee.numeric_std.all,但是当我做'+'时发生错误"found '0' definitions of operator "+",无法确定“+”的精确重载匹配定义。所以我将另一个库更改为另一个库 ieee.std_logic_arith.all ans 将添加操作作为一个组件,它可以工作。 当我使用 testbench 模拟我的代码时,发生错误:实体端口 xin 与组件端口的签名类型不匹配。 我认为这个错误与我的图书馆有关。 谁能帮帮我?
新
我不使用加法器作为组件,下面的代码有效
adder: process(clk)
begin
if (clk'event and clk = '1')then
if enable1='1' then
add1 <= (x0(7)&x0) + (x15(8)&x15);
add2 <= (x1(7)&x1) + (x14(8)&x14);
add3 <= (x2(7)&x2) + (x13(8)&x13);
add4 <= (x3(7)&x3) + (x12(8)&x12);
add5 <= (x4(7)&x4) + (x11(8)&x11);
add6 <= (x5(7)&x5) + (x10(8)&x10);
add7 <= (x6(7)&x6) + (x9(8)&x9);
add8 <= (x7(7)&x7) + (x8(8)&x8);
end if;
end if;
end process adder;
我的测试平台的库使用use ieee.numeric_std.all;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;
ENTITY tb_signedinput IS
END tb_signedinput;
ARCHITECTURE behavior OF tb_signedinput IS
-- Component Declaration
COMPONENT signedinput is
port( Clk : in std_logic;
reset : in std_logic;
enable1 : in std_logic;
Xin : in signed(7 downto 0);
Yout : out signed(19 downto 0)
);
END COMPONENT;
--Inputs
signal Clk : std_logic := '0';
signal reset : std_logic := '0';
signal Xin : signed(7 downto 0) := (others => '0');
signal enable1 : std_logic := '0';
--Outputs
signal Yout : signed(19 downto 0);
-- Array
constant MEMSIZE: integer :=99;
type testarray is array (MEMSIZE downto 0) of signed(7 DOWNTO 0);
signal testvectors: testarray;
shared variable vectornum,outnum: integer;
-- Clock period definitions
constant Clk_period : time := 10 ns;
BEGIN
-- Component Instantiation
uut: signedinput PORT MAP( Clk => Clk,
reset => reset,
Xin => Xin,
enable1 =>enable1,
Yout => Yout );
错误仍然存在:
Entity port xin does not match with type std_logic_vector of component port
Entity port yout does not match with type std_logic_vector of component port
因此,我再次将加法器更改为
add1 <= resize(x0,9) + x15;
语法良好但在测试台中出现同样的错误..
我的 ISE 类型或库类型有误吗? 谢谢!
您在 adder1
中的加法表达式无效,因为当 a1
和 a2
的范围是 7 到 0 时,您试图索引元素“8”。
假设你正在尝试签署扩展它看起来更像这样:
q <=(a1(7)&a1 + a2(7)&a2);
“+”运算符的优先级高于“&”,因此您尝试添加 a1 + a2(7)
即 signed + std_logic
。除了逻辑错误之外,numeric_std
中没有定义重载。
这个有效:
q <=(a1(7)&a1) + (a2(7)&a2);
但这不是使用 numeric_std
时实现符号扩展的规范方式。您只需要左侧项的大小与 q
相同。带符号的“+”运算符将负责自动扩展其右侧的符号。
q <= resize(a1, q'length) + a2; -- Sign extend a1 and add
这提供了更清晰的代码,说明它在做什么而不依赖于非标准 std_logic_arith
。
关于 xin
类型不匹配的实际错误在您的代码中并不明显。有可能您的旧版本 signedinput
在其端口上编译了不同的类型并且没有更新库。
凯文让它看起来很难,所以我想我会展示一些可以很好解释的东西:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity adder1 is
port (
a1: in signed (7 downto 0);
a2: in signed (7 downto 0);
clk: in std_logic;
enable1: in std_logic;
q: out signed (8 downto 0)
);
end entity;
architecture behavioral of adder1 is
begin
UNLABELLED:
process(clk)
begin
if clk'event and clk ='1' then
if enable1 = '1' then
q <= a1(7) & a1 + a2 ;
end if;
end if;
end process;
end architecture;
q
的分配看起来很简单,所以值得解释一下。
numeric_std 中的“+”表示有符号会扩展较短的操作数以匹配较长操作数的长度。
剩下的就是优先魔法
“+”和“&”优先级相同,即按从左到右的textual顺序求值,即用连接符进行符号扩展首先(参见 IEEE Std 1076-2008,9.2 运算符)。
“+”运算符将左操作数视为较长,并将右操作数与其长度相匹配(请参阅程序包 numeric_std“+”,用于 L、R:有符号)。它通过在找到两个操作数的长度的 MAX 之后对两个操作数使用带符号的 RESIZE 以及将元值转换为“X”来实现这一点。
如果右操作数也更长,则有效:
q <= a1 + (a2(7) & a2) ;
这里我们需要括号将连接运算符的结果关联为加法运算符的右操作数,因为这两个运算符的优先级相同,否则会按文本顺序遇到。
没有理由再次调用调整大小,它只是通过串联进行一位符号扩展,基于知道符号包含在二进制补码的左侧元素(位)中。
在 VHDL 标准中找不到术语规范。
就 Xin 而言,我同意 Kevin 的观点,可能需要重新分析某些内容,以便在同一个包中找到对 signed 的两个引用。
设计中使用的每个声明都是唯一的。如果说端口映射中的实际依赖包 std_logic_arith 中的类型签名声明,而正式依赖包 numeric_std 中签名的声明,它们将是不同的类型。