web-dev-qa-db-fra.com

Pourquoi ne puis-je pas incrémenter ce `std_logic_vector`

Que se passe t-il ici? Pourquoi est-ce que je reçois une "incompatibilité de type d'argument opérateur" et que puis-je faire pour la résoudre?

--
-- 32-bit counter with enable and async reset
--
architecture synthesis1 of counter_32bit is    
signal nextvalue : std_logic_vector ( 31 downto 0 );    
begin

  --
  -- combo
  --
  nextvalue <= value + 1; -- here

  --
  -- sequential
  --
  ff:process( clk, rst )
  begin

    if( rst = '1' ) then
      value <= 0; -- and here...
    elsif( clk'event and ( clk ='1' ) ) then
      if( ena = '1' ) then
         value <= nextvalue;
      end if;
    end if;

  end process ff;    

end synthesis1;

Merci

12
Marty

vous ne pouvez pas incrémenter std_logic directement, vous devez le convertir en unsigned et redonner le résultat en std_logic_vector à l'aide du package numeric_std

use ieee.numeric_std.all
...
nextvalue <= std_logic_vector( unsigned(value) + 1 );

Voir Comment effectuer l'addition de STD_LOGIC_VECTOR à l'aide de IEEE.NUMERIC_STD par exemple.

24
danielpoe

Une autre façon est de surcharger le "+" dans ce cas, vous pouvez écrire:

function "+" ( a : std_logic_vector; b : integer ) return std_logic_vector is
    variable result : unsigned(a'range);
begin
    result := unsigned( a ) + 1 ;
    return std_logic_vector( result ) ;
end function ;

créer un paquet et inclure cette fonction dans ce paquet et cela fera l'affaire. Une autre chose comprend le paquet ieee numeric_std car il contient les fonctions de conversion.

3
AbKDs

Essayez ce code:

use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
...
nextvalue <= value + "1";

Dans mon cas, cette solution fonctionne!

3
Vladislav

Outre les réponses déjà fournies, vous pouvez réécrire le code en définissant nextvalue comme ayant le type de données unsigned (ci-dessous). Notez l'utilisation de nextvalue <= to_unsigned(0, 32); pour effacer le compteur et l'utilisation de rising_Edge(clk) pour déclencher un bord montant.

-- 32-bit counter with enable and async reset
architecture synthesis1 of counter_32bit is    
    signal nextvalue : unsigned ( 31 downto 0 );    
begin

    ff:process( clk, rst )
    begin

        if( rst = '1' ) then
            nextvalue <= to_unsigned(0, 32); -- reset the count
        elsif rising_Edge(clk) then
            if( ena = '1' ) then
                nextvalue <= nextvalue + 1;  -- increment the count
            end if;
        end if;

    end process ff;

    -- Concurrent assignment statement
    value <= std_logic_vector(nextvalue);

end synthesis1;

Cette forme d’assignation simultanée semble être la méthode privilégiée pour mettre à jour un compteur à partir de ce que j’ai trouvé dans les livres et en ligne.

De même, si vous continuez à utiliser le type std_logic_vector pour nextvalue, la méthode recommandée pour l'effacer semble être nextvalue <= (others => '0'); et non simplement nextvalue <= 0;.

2
Engineero

En un mot, STD_LOGIC_VECTOR est simplement un vecteur de bits. Cela ne signifie rien par lui-même, vous ne pouvez donc pas vous attendre à ce que vhdl assume sémantiquement qu’une opération d’incrémentation fonctionnera. Les autres articles ici sur la conversion en non-signé devraient faire l'affaire.

1
Jun

Cela fonctionnera également:

nextvalue <= value + '1'; 

Ne sais pas si vous êtes vraiment versé dans le VHDL. La syntaxe suivante est logiquement correcte si vous utilisez le paquet std_logic_arith 

0
Vijay