web-dev-qa-db-fra.com

Erreur lors de l'ajout de std_logic_vectors

Je veux avoir un module simple qui ajoute deux std_logic_vectors. Cependant, lorsque vous utilisez le code Ci-dessous avec l'opérateur +, il ne synthétise pas. 

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;

Le message d'erreur que je reçois de XST

La ligne 17. + ne peut pas avoir de tels opérandes dans ce contexte.

Est-ce que je manque une bibliothèque? Si possible, je ne veux pas convertir les entrées en nombres naturels.

Merci beaucoup

17
Mike21

Comment voulez-vous que le compilateur sache si vos std_logic_vectors sont signés ou non signés? L'implémentation d'Adder n'est pas la même dans ces deux cas, vous devez donc explicitement dire au compilateur ce que vous voulez qu'il fasse ;-)

Remarque: La syntaxe VHDL en surbrillance dans StackOverflow est de mauvaise qualité. Copiez/collez ce code dans votre éditeur VHDL préféré pour le lire plus facilement.

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;
22
Aurélien Ribon

Ne pas utiliser std_logic_arith - J'ai écrit à ce sujet (plus ou moins :).

Do utilise numeric_std - et utilise le bon type sur les ports de votre entité. Si vous faites de l'arithmétique, utilisez des types numériques (soit des entiers, soit des vecteurs (non) signés, selon le cas). Ils vont très bien synthétiser.

std_logic_vectors sont bons pour 

  • quand vous ne vous souciez pas des valeurs numériques (un ensemble de bits de contrôle, des bits de données aléatoires)
  • lorsque vous ne connaissez pas le type de l'entrée (par exemple, un additionneur pouvant fonctionner à la fois sur des nombres signés et non signés en fonction d'un indicateur de contrôle).
5
Martin Thompson

Bon conseil de @Aurelien d'utiliser numeric_std.

N'oubliez pas que l'ajout de deux valeurs 32 bits peut générer une valeur 33 bits et décide de la manière dont vous souhaitez gérer le débordement.

0
George