Vhdl 添加标准逻辑向量时出错

Vhdl 添加标准逻辑向量时出错,vhdl,fpga,Vhdl,Fpga,我想要一个简单的模块,添加两个std_逻辑向量。但是,在使用代码时 下面使用+运算符,它不会合成 library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; entity add_module is port( pr_in1 : in std_logic_vector(31 downto 0); pr_in2 : in std_logic_vector(31 downto 0

我想要一个简单的模块,添加两个std_逻辑向量。但是,在使用代码时 下面使用+运算符,它不会合成

library IEEE; 
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity add_module is
        port(
  pr_in1   : in std_logic_vector(31 downto 0);
  pr_in2   : in std_logic_vector(31 downto 0);
  pr_out   : out std_logic_vector(31 downto 0)  
        );
end add_module;

architecture Behavior of add_module is

begin

    pr_out <= pr_in1 + pr_in2;

end architecture Behavior;
IEEE库;
使用IEEE.std_logic_1164.all;
使用IEEE.std_logic_arith.all;
实体添加模块为
港口(
pr_in1:in标准逻辑向量(31到0);
pr_in2:in标准逻辑向量(31到0);
pr_out:out标准逻辑向量(31到0)
);
终端添加模块;
add_模块的体系结构行为是
开始

pr_out您希望编译器如何知道您的std_逻辑_向量是有符号的还是无符号的?加法器的实现在这两种情况下是不一样的,所以您需要显式地告诉编译器您希望它做什么;-)

注意:StackOverflow中的VHDL语法突出显示很糟糕。将此代码复制/粘贴到首选的VHDL编辑器中,以便更轻松地阅读

IEEE库;
使用IEEE.std_logic_1164.all;
--使用IEEE.std_logic_arith.all;——不要用这个
使用IEEE.numeric_std.all;——使用它,它是一个更好的编码指南
--此外,永远不要使用IEEE.std_unsigned.all或IEEE.std_signed.all,这些
--是有史以来最糟糕的图书馆。他们会自动投射你所有的向量
--签署或不签署。讨论可维护性和强类型语言。。。
实体添加模块为
港口(
pr_in1:in标准逻辑向量(31到0);
pr_in2:in标准逻辑向量(31到0);
pr_out:out标准逻辑向量(31到0)
);
终端添加模块;
add_模块的体系结构行为是
开始
--在这里,您首先需要将输入向量强制转换为有符号或无符号
--(根据您的需要)。然后,您将被允许添加它们。
--结果将是有符号或无符号向量,因此您将无法
--将其直接指定给输出向量。你首先需要投
--将结果转换为标准逻辑向量。
--这是用VHDL进行计算的最安全和最好的方法。

@aurelian建议您使用数字标准

请记住,添加两个32位值会产生一个33位值,并决定如何处理溢出。

不要使用
std\u logic\u arith
-我已经(在某些长度:)

请务必使用数字_std-并在实体端口上使用正确的类型。如果您在做算术,请使用数字类型(整数或(无)符号向量,视情况而定)。他们会合成得很好

std\u逻辑\u向量
s适用于

  • 当您不关心数值时(一组控制位、一些随机数据位)
  • 当您不知道输入的类型时(比如一个加法器,它可以根据控制标志对有符号和无符号数字进行运算)

    • 解决此错误的简单方法是:
      添加未签名的库,
      之后,代码开始工作

      使用

      ieee.std\u logic\u unsigned.all;
      
      pr_out我建议查看Martin的链接。正如@Martin Thompson所说,不建议使用此库。你能解释一下吗?所有内容都在Martin Thompson答案中的链接中
      std\u logic\u arith``std\u logic\u unsigned
      std\u logic\u signed
      是synopsis开发的非标准库
      numeric\u std
      是标准库。另外,我在主题上的2美分:使用numeric\u std可以防止在编写代码时由于在处理数字时使用
      有符号的
      无符号的
      类型而不是通用的
      std\u logic\u vector
      而容易出错。
      library IEEE; 
      use IEEE.std_logic_1164.all;
      -- use IEEE.std_logic_arith.all; -- don't use this
      use IEEE.numeric_std.all; -- use that, it's a better coding guideline
      
      -- Also, never ever use IEEE.std_unsigned.all or IEEE.std_signed.all, these
      -- are the worst libraries ever. They automatically cast all your vectors
      -- to signed or unsigned. Talk about maintainability and strong typed language...
      
      entity add_module is
        port(
          pr_in1   : in std_logic_vector(31 downto 0);
          pr_in2   : in std_logic_vector(31 downto 0);
          pr_out   : out std_logic_vector(31 downto 0)  
        );
      end add_module;
      
      architecture Behavior of add_module is
      begin
      
        -- Here, you first need to cast your input vectors to signed or unsigned 
        -- (according to your needs). Then, you will be allowed to add them.
        -- The result will be a signed or unsigned vector, so you won't be able
        -- to assign it directly to your output vector. You first need to cast
        -- the result to std_logic_vector.
      
        -- This is the safest and best way to do a computation in VHDL.
      
        pr_out <= std_logic_vector(unsigned(pr_in1) + unsigned(pr_in2));
      
      end architecture Behavior;
      
      ieee.std_logic_unsigned.all;
      pr_out <= pr_in1 + pr_in2;