vhdl中的信号应该是有符号/无符号的,以执行算术运算吗?

时间:2016-06-09 11:17:20

标签: vhdl unsigned

我正在练习一些基本的vhdl程序。现在我遇到了算术运算。我使用了bit_vector并直接乘以输入信号,但是错误"对于中缀运算符没有可行的条目" 该计划如下:

   entity multiplier is
   port(a,b : in bit_vector(3 downto 0);
   c: out bit_vector(7 downto 0));
   end  multiplier;

   architecture ar of multiplier is

   begin

   c<=(a*b);

   end ar;

但是我遇到了这个与std_logic_vector

配合使用的程序
   library IEEE;
   use IEEE.STD_LOGIC_1164.ALL;
   use IEEE.NUMERIC_STD.ALL;
   entity Multiplier_VHDL is
   port(
  Nibble1, Nibble2: in std_logic_vector(3 downto 0);
  Result: out std_logic_vector(7 downto 0)
  );
  end entity Multiplier_VHDL;

 architecture Behavioral of Multiplier_VHDL is
 begin

 Result <= std_logic_vector(unsigned(Nibble1) * unsigned(Nibble2));

 end ;

我的问题是:

1.cant我们只需添加2个信号位c&lt; = a + b,就像我们在verilog中那样做?

2.应该对信号进行签名/无符号执行算术运算吗?

3.喜欢默认签名的c,vhdl / verilog怎么样?

4.签名&amp;使用ieee.std_logic_arith.all中的unsigned存在并使用IEEE.NUMERIC_STD.ALL吗?

2 个答案:

答案 0 :(得分:1)

1。不能像在verilog中那样添加2个信号位c <= a + b吗?

VHDL是一种强类型语言,这意味着在为彼此分配不同类型的东西时它是严格的。 Verilog可能会让你乘以一个简单的位向量;你知道操作数的类型和结果的格式,这对你的设计过程来说很好。在VHDL中,如果设计师知道数字的格式是什么,那就不够好了,编译器也想知道这个。在您的示例中,编译器不知道您的向量是否表示无符号数,有符号,不定点等。通过将它们转换为无符号,您明确告诉它数字格式是什么。一个更好的解决方案是将这些作为类型unsigned贯穿始终,以避免类型转换。

VHDL强类型的另一个优点是,它可以帮助在编译阶段而不是在仿真或FPGA设备上捕获由数字格式存储中的错误引起的错误。通常,它可以节省在设计周期早期捕获错误的时间。如果您在线搜索&#34;强类型&#34;你会发现有关这个主题的更多讨论。

2。信号是否应该有符号/无符号来执行算术运算?

如上所述,如果你想坚持使用标准库,那么最好给你的信号一个有意义的类型。想想那个试图在10年后理解你的代码的人(甚至可能是你),如果它清楚数字格式是什么,他们的生活会变得更容易。

3。就像默认签名的c一样,vhdl / verilog是什么?

您的示例代码中的

c在VHDL中没有默认签名,它具有您声明的任何类型。如果您使用unsigned进行相乘,结果也将是unsigned,因此这将是我将用于结果的类型。如果结果信号的类型与操作的返回类型不匹配,则这将是编译器错误。

4。是signed&amp; unsigned中存在use ieee.std_logic_arith.all并使用IEEE.NUMERIC_STD.ALL相同的内容?

不,不建议使用std_logic_arith,因为此库不是VHDL标准的一部分。如果您熟悉numeric_std中的数字格式,则不需要使用任何其他库进行整数运算。

答案 1 :(得分:0)

VHDL中使用的常用矢量类型是std_logic_vector包中的ieee.std_logic_1164,而不是bit_vector

但是,此向量类型只是std_logic元素的集合,没有定义的算术运算。因此,可用于获取算术运算的标准VHDL包是numeric_std

将这些用于无符号算术的VHDL-2002兼容代码,它将显示:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity multiplier is
  port(a, b : in  std_logic_vector(3 downto 0);
       c    : out std_logic_vector(7 downto 0));
end multiplier;

architecture ar of multiplier is
begin
  c <= std_logic_vector(unsigned(a) * unsigned(b));
end ar;

但是,您可以选择将a,'b'和'c'定义为unsigned,以简化代码,如:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity multiplier is
  port(a, b : in  unsigned(3 downto 0);
       c    : out unsigned(7 downto 0));
end multiplier;

architecture ar of multiplier is
begin
  c <= a * b;
end ar;

signed包中还定义了numeric_std种类型。

在VHDL-2008中,提供了numeric_std_unsigned包,它提供std_logic_vector类型的算术运算,因此代码可以是:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;

entity multiplier is
  port(a, b : in  std_logic_vector(3 downto 0);
       c    : out std_logic_vector(7 downto 0));
end multiplier;

architecture ar of multiplier is
begin
  c <= a * b;
end ar;

回答4个问题:

  1. 必须为操作数定义算术运算,这可以通过使用unsigned包中numeric_std类型的转换,或通过使用numeric_std_unsigned中的运算符来完成}包。

  2. 对于VHDL-2002是,对于VHDL-2008,可以使用numeric_std_unsigned包。

  3. 见上文。

  4. std_logic_arith包是Synopsys包,因此请改用numeric_stdnumeric_std_unsigned