我的输入数据是2的恭维,我设计输入是有符号数,所有操作都使用有符号数,我使用ieee.numeric_std.all库,但当我做'+'时发生错误“找到”运算符“+”的0'定义无法确定“+”的精确重载匹配定义。所以我将另一个库改为另一个库ieee.std_logic_arith.all,将add操作作为一个组件,它可以工作。 当我使用testbench模拟我的代码时,发生错误:实体端口xin与组件端口的签名类型不匹配。 我认为这个错误与我的图书馆有关。 有谁可以帮助我?
我不使用adder作为组件,下面的代码可以使用
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;
语法很好,但在testbench中有相同的错误..
我的ISE类型或库类型有错误吗? 谢谢!
答案 0 :(得分:1)
adder1
中的添加表达式无效,因为当a1
和a2
的范围为7 downto 0时,您尝试索引元素“8”。
假设您正在尝试签名扩展,它会看起来更像这样:
q <=(a1(7)&a1 + a2(7)&a2);
“+”运算符的优先级高于“&amp;”因此,您尝试添加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
的旧版本,但未更新库。
答案 1 :(得分:0)
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中带符号的“+”符号将扩展较短的操作数以匹配较长操作数的长度。
其余的是优先魔法。
“+”和“&amp;”具有相同的优先级,这意味着它们以从左到右的文本顺序进行评估,这意味着首先执行带有连接运算符的符号扩展(参见IEEE Std 1076-2008,9.2运算符)。
“+”运算符将左操作数视为更长,并将右操作数与其长度匹配(请参阅封装numeric_std“+”表示L,R:signed)。它通过在找到两者的长度的MAX之后在两个操作数上使用带符号的RESIZE来实现这一点,同时将元值转换为'X'。
如果右操作数也较长,则可以正常工作:
q <= a1 + (a2(7) & a2) ;
这里我们需要括号将连接运算符的结果与add运算符的右操作数相关联,因为这两个运算符具有相同的优先级,否则将以文本顺序遇到。
没有理由再次调用resize,它只是通过连接的一位符号扩展,基于知道符号体现在两个恭维数的左手元素(位)。
VHDL标准中没有“规范”一词。
至于Xin,我同意Kevin的意见,可能需要重新分析一些内容,以便在同一个包中找到对签名的引用。
设计中使用的每个声明都是唯一的。如果说端口映射中的实际值取决于包std_logic_arith中的类型signed声明,并且形式依赖于signed in package numeric_std的声明,则它们将具有不同的类型。