VHDL: conversion d'un type INTEGER en STD_LOGIC_VECTOR

  • J'ai construit un compteur mod-16, et le résultat de sortie est un INTEGER (tous les exemples que j'ai vus utilisaient INTEGER).

    J'ai construit un décodeur d'affichage hexadécimal à 7 segments, et son entrée est un STD_LOGIC_VECTOR (l'a écrit de cette façon parce qu'il était facile de tracer la table de vérité).

    Je voudrais connecter la sortie du compteur à l'entrée du décodeur, mais j'obtiens des erreurs de «type mismatch» lorsque j'essaye de compiler dans QuartusII.

    Existe-t-il un moyen de convertir un type INTEGER en un type STD_LOGIC_VECTOR dans une liste VHDL?

  • Comme d'autres l'ont dit, utilisez ieee.numeric_std, jamais ieee.std_logic_unsigned, qui n'est pas vraiment un package IEEE.

    Cependant, si vous utilisez des outils prenant en charge VHDL 2008, vous pouvez utiliser le nouveau package ieee.numeric_std_unsigned, ce qui fait essentiellement std_logic_vector se comportent comme non signés.

    De plus, comme je ne l'ai pas vu explicitement, voici un exemple de code réel pour convertir un entier (non signé) en un std_logic_vector:

    use ieee.numeric_std.all;
    ...
    my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));
    
  • Comme le dit LoneTech, use ieee.numeric_std est votre ami. Vous pouvez convertir un std_logic_vector à un integer, mais vous devrez le lancer comme signed ou unsigned first (car le compilateur n'a aucune idée de ce que vous voulez dire). VHDL est un langage fortement typé. J'ai écrit plus à propos de ce sujet sur mon blog

    Fondamentalement, je changerais votre convertisseur 7seg pour prendre un integer (ou en fait un natural, étant donné qu'il ne traitera que des nombres positifs) - la conversion est alors une simple recherche de tableau. Configurez un tableau constant avec les conversions et indexez-le simplement avec l'entier que vous utilisez sur l'entité en tant qu'entrée.

    Merci pour cela. J'apprécie beaucoup vos commentaires. J'étais en quelque sorte dans une position d'AT, apprenant le VHDL pour aider un prof qui était un peu ébranlé sur les concepts de programmation. Je vais lui transmettre vos informations - le manuel que nous avons utilisé ne s'est pas penché sur les questions de «moralité» VHDL.

    C'est moins une question de «moralité» qu'une garantie de cohérence. La bibliothèque numeric_std est un véritable standard institué par l'IEEE, tandis que la bibliothèque std_logic_unsigned a été constituée par un éditeur et adoptée dans l'industrie sans véritable définition formelle. Il n'y a aucune garantie de compatibilité entre fournisseurs avec les bibliothèques non standard, bien que cela fonctionne généralement bien. Il est cependant bon de passer à la norme maintenant.

  • Disons que votre compteur 4 bits avait une sortie INTEGER SOME_INTEGER, et que vous vouliez le convertir en un STD_LOGIC_VECTOR 4 bits

    SOME_VECTOR <= conv_std_logic_vector(SOME_INTEGER, 4);
    

    Vous pouvez également l'utiliser pour initialiser des vecteurs avec des nombres significatifs

    SOME_VECTOR <= conv_std_logic_vector(9, 4); -- instead of "1001"
    

    Je pense que vous devrez peut-être ajouter "use IEEE.STD_LOGIC_ARITH.ALL;" et / ou STD_LOGIC_UNSIGNED.

    L'opération complémentaire est conv_integer (vector). J'aime utiliser ceci quand je fais des comparaisons. Alors je pourrais déclarer

    constant SOME_CONSTANT : integer := 999;
    

    Et puis, plus tard, je peux l'utiliser dans une instruction if

    if (conv_integer(SOME_VECTOR)=SOME_CONSTANT)
      then OTHER_VECTOR <= (others => '0');
    end if;
    

    EDIT: Vous ne devriez pas avoir besoin de déclarer la variable comme un entier. Essayez de remplacer la déclaration par std_logic_vector. Les opérateurs + et - fonctionnent sur std_logic_vectors.

    Ne faites pas ça! Utilisez numeric_std (voir LoneTech et mes réponses)

    Si vous avez une meilleure façon de le faire, c'est bien, mais ma suggestion fonctionne, donc je pense que votre vote défavorable n'était pas nécessaire. J'utilise std_logic_arith depuis des années et je n'ai jamais eu de problème avec. Je pense que les craintes que les fournisseurs modifient leurs implémentations ne sont pas fondées; quel fournisseur sensé risquera de casser les conceptions de ses clients?

    Vous avez déjà une réponse à ce que le fournisseur mettra volontairement des éléments spécifiques au fournisseur dans l'espace de noms IEEE. Cela reste grossier, en particulier lorsqu'il s'agit de valeurs signées * et * non signées.

    "Les opérateurs + et - fonctionnent sur std_logic_vectors." AFAIK, ils ne fonctionnent pas, à moins que je ne comprenne mal votre sens. il est généralement nécessaire de convertir en un type qui contient d'abord les données signées / non signées.

  • Vous pourriez être intéressé par l'utilisation des types unsigned et signed de ieee.numeric_std. Ils sont compatibles avec std_logic_vector, mais ont une interprétation numérique (binaire ou 2-complément). Il y a aussi la possibilité de mettre une telle interprétation sur std_logic_vector, mais c'est non recommandé.

  • Comme l'indique la réponse principale, la méthode recommandée est la suivante:

    use ieee.numeric_std.all;
    ...
    my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));
    

    Cependant, je voudrais expliquer pourquoi cela est recommandé, et pourquoi VHDL a une manière si compliquée de convertir des entiers en std_logic_vectors.

    Cela se résume à la façon dont ces types sont perçus par les outils.

    Un standard_logic_vector est littéralement un groupe de 1 ou de 0. J'ai 10001. De quel numéro s'agit-il? En fait ça dépend. Est-il signé ou non signé? Ths SLV ne sait pas ou ne se soucie pas. Combien de bits? Eh bien, combien de temps dure votre SLV?

    Un entier est signé, et généralement 32 bits (si je me souviens bien).

    Étape 1: Rendre mon entier plus court et non signé. C'est cette partie:

    to_unsigned(my_int, my_slv'length));
    

    "J'ai cet entier, je veux qu'il ne soit pas signé et je veux qu'il tienne dans la longueur de mon SLV. "

    Étape 2: Ensuite, prenez ces bits et utilisez-les pour piloter le my_slv.

    my_slv <= std_logic_vector(...)
    

    "Prends ces morceaux et utilise-les pour conduire mon slv"

    (Une note sur la terminologie. A <= B en VHDL est lu à haute voix comme "A est entraîné par B")

    Combiné, cela vous permet:

    my_slv <= std_logic_vector(to_unsigned(my_int, my_slv'length));
    

    Lorsque vous venez d'un contexte de programmation traditionnel, il est très facile de rester coincé dans une façon de penser la programmation. Mais en VHDL, le code que vous écrivez a des implications physiques sur le matériel. Savoir pourquoi cette méthode fonctionne et est recommandée est un pas de plus vers la réflexion sur ce que vous écrivez en termes matériels.

    Astuce bonus: les fonctions préfixées par to_ sont celles qui raccourcissent / modifient les opérandes. Ils les rendent non signés ou d'une certaine longueur ou les deux. C'est pourquoi to_unsigned vous oblige à spécifier la longueur. Les fonctions sans to_ (straight std_logic_vector (...) dans cet exemple) sont utilisées lorsque les types sont déjà directement compatibles. "Prenez ces bits et mettez-les dans ce type, aucune modification requise". Ceux-ci n'ont pas d'argument de longueur car les deux côtés sont déjà identiques. Donc, lorsque je construis des choses comme ça, je n'ai pas besoin de le chercher, je pense juste à la façon dont je change les données.

  • Pour convertir un entier en std_logic_vector, vous avez plusieurs options. Utilisation de numeric_std:

    vect <= std_logic_vector( to_unsigned( your_int, vect'length));
    

    ou

    vect <= std_logic_vector( to_signed( your_int, vect'length));
    

    Utilisation de std_logic_arith:

    vect <= conv_std_logic_vector( your_int, vect'length);
    

    std_logic_arith n'est pas un standard ieee, mais la plupart des outils le compilent dans la bibliothèque IEEE et il est largement utilisé.

Licence sous CC-BY-SA avec attribution


Contenu daté avant 26/06/2020 09:53