首页 文章

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

提问于
浏览
0

我正在练习一些基本的vhdl程序 . 现在我遇到了算术运算 . 我使用了bit_vector并直接乘以输入信号,但它错误 "No feasible entries for infix operator" . 程序如下:

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 we simply add 2 signal bits c<=a+b as we do in verilog?

2.should a signal be signed/unsigned to perform arithmetic operations?

3.like c which is signed by default,what about vhdl/verilog?

4.are signed & unsigned present in use ieee.std_logic_arith.all and use IEEE.NUMERIC_STD.ALL same?

2 回答

  • 0

    1.我们只是像在verilog中那样添加2个信号位c <= a b?

    VHDL是一种强类型语言,这意味着它在分配不同类型的东西时是相当严格的 . Verilog可能会让你乘以一个简单的位向量;你知道操作数的类型和结果的格式,并且's fine for your design process. In VHDL, it'不够好,以至于你作为设计者知道数字的格式,编译器也想知道这一点 . 在您的示例中,编译器不知道您的向量是表示无符号数,有符号,定点等 . 通过将它们转换为无符号,您明确告诉它数字格式是什么 . 一个更好的解决方案是将这些作为整个类型 unsigned ,以避免类型转换 .

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

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

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

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

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

    4.签名和未签名是否存在使用ieee.std_logic_arith.all并使用IEEE.NUMERIC_STD.ALL相同?

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

  • 1

    在VHDL中使用的常用向量类型是包 ieee.std_logic_1164 中的 std_logic_vector ,而不是 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;
    

    numeric_std 包中还定义了 signed 类型 .

    在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个问题:

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

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

    • 见上文 .

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

相关问题