[Exercices] aide exercice vhdl
Répondre à la discussion
Affichage des résultats 1 à 11 sur 11

aide exercice vhdl



  1. #1
    Leond95

    aide exercice vhdl


    ------

    Bonsoir,

    je suis un débutant en vhdl, est ce que vous pouvez me donner des pistes pour coder le module suivant.

    merci

    --****************************** ***************
    -- module gestion_compas pour boussole CMPS03 ou CMPS10
    --****************************** ****************
    --entrées:
    --clk_50M : hologe 50MHz
    --raz_n: reset actif à 0 => initialise le circuit
    --in_pwm_compas: signal PWM de la boussole, durée varie de 1ms à 36,9ms
    --****************************** ****************************** **
    -- sorties:
    -- data_compas : valeur du cap réel exprimé en degré codé sur 9 bits
    --****************************** ****************************** *******

    -----

  2. #2
    jiherve

    Re : aide exercice vhdl

    Bonjour,
    as tu déjà une petite idée du principe d'acquisition ?
    As tu dessiné un chronogramme du signal in_pwm ?
    Je peux t'aider mais je ne ferais le boulot à ta place.
    JR
    l'électronique c'est pas du vaudou!

  3. #3
    Leond95

    Re : aide exercice vhdl

    Bonjour,

    Si j'ai une idée, en variant la pwm en entrée, le dgrée en sortie varie, pour la pwm je pense au blocs suivants:
    - Un compteur libre sur N bits piloté par une horloge de référence clk.
    - Un comparateur sur N bits qui compare la sortie du compteur avec son modulo (FREQ : ce qui permet de fixer la fréquence de la PWM). La sortie du comparateur assure la remise à zéro du compteur.
    - Un comparateur sur N bits qui compare la sortie du compteur avec le rapport cyclique désiré (DUTY). La sortie de ce comparateur génère la sortie pwm_out.

    mais comment transformé cette valeur en degrée, je n'ai pas d'idée.

    Cordialement

  4. #4
    jiherve

    Re : aide exercice vhdl

    re
    ton capteur fourni une impulsion dont la durée est proportionnelle à l'angle (100uS/°), il suffit donc de mesurer cette durée. Il n'y a pas besoin de comparateur.
    il suffit donc d'un compteur qui ne comptera que durant la partie haute du signal dont la sortie sera donc image de la valeur angulaire en degré.
    maintenant l'horloge d'entrée est à 50MHz et les durées à mesurer varient de 1ms à 36,9 ms il existe donc deux façons de faire ce comptage lesquelles?
    JR
    l'électronique c'est pas du vaudou!

  5. A voir en vidéo sur Futura
  6. #5
    Leond95

    Re : aide exercice vhdl

    Bonsoir,

    franchement je n'ai aucune idée, j'ai cherché sur internet mais j'ai rien trouvé.

  7. #6
    jiherve

    Re : aide exercice vhdl

    Bonjour
    il ne faut pas chercher il faut réfléchir :
    Quelle durée peut on mesurer avec un compteur 9 bits (= 512) tournant à 50Mhz (T =20ns)?
    un peu d'arithmétique CE1 : 512 * T = 10,24 µS
    C'est donc inadapté pour mesurer des dizaines de mS , on peut donc:
    Soit diviser la fréquence d'horloge primaire avant de l'utiliser pour le compteur ,le codage étant de 100µs/° on peut donc choisir une fréquence de 10kHz pour le comptage, il faudra donc diviser le 50MHz par 5000 au moyen d'un compteur/diviseur annexe, ce compteur aura donc 13 bits.
    Soit augmenter le nombre de bits du compteur de mesure, la valeur maximale étant de l'ordre de 40ms il faut pouvoir compter jusqu’à 2_000_000 soit 21 bits
    On note, ce qui est assez évident, que les deux solutions nécessitent à peu prés le même nombre de bascules.
    L'avantage de la première solution c'est qu'a un offset pres (1mS) la sortie du compteur est la valeur attendue.
    La seconde solution présente elle une bien meilleure résolution de mesure mais la sortie du compteur devra être travaillée pour obtenir la sortie espérée.
    JR
    l'électronique c'est pas du vaudou!

  8. #7
    Leond95

    Re : aide exercice vhdl

    Bonjour,

    est ce que c'est le bon code

    Code:
      library IEEE;
      use IEEE.std_logic_1164.all;
      use IEEE.STD_LOGIC_ARITH.ALL;
      use IEEE.STD_LOGIC_UNSIGNED.ALL;
      use ieee.numeric_std.all;
    -----------------------------------entity----------------------------------------
      entity compas is
        Port ( Clk_50M,raz_n,in_pwm_compas : in  STD_LOGIC;    -- Horloge 50 Mhz et Reset Asynchrone
               data_compas: out STD_LOGIC_VECTOR (12 downto 0));   -- afficheur 7 segment
      end compas;
    -----------------------------------ARCHITECTURE---------------------------------
    architecture arch of compas is
    
      signal count: integer:=1;
      signal tmp : std_logic := '0';
      signal clk_1khz : std_logic;
      signal temp: std_logic_vector(12 downto 0);
      
    
      begin
    -----------------------DIVISEUR DE FREQUENCES---------------------------------
      process(Clk_50M,raz_n)
        begin
          if(raz_n='1') then
            count<=1;
            tmp<='0';
          elsif(clk'event and clk='1') then
            count <=count+1;
            if (count = 5000) then
              tmp <= NOT tmp;
              count <= 1;
            end if;
          end if;
        end process;
        clk_1khz <= tmp;
      ---------------------------COUNTER----------------------------------------
       process(Clk_1khz,in_pwm_compas,raz_n) begin
         if raz_n = '0' then
             temp<= (others=>'0');
        elsif(in_pwm_compas = '1' and in_pwm_compas'event)then
          if(Clk_1khz = '1')then
              temp <= temp + 1;
           else temp <= (others => '0');
             end if;
          end if;
       end process;
       data_compas <= temp;
       end arch;

  9. #8
    jiherve

    Re : aide exercice vhdl

    bonsoir,
    c'est bien tu as bossé
    qqs remarques :
    1 :dans la spec on lit :
    raz_n: reset actif à 0 => initialise le circuit dans ton code il y a les deux cas
    data_compas : valeur du cap réel exprimé en degré codé sur 9 bits tu utilises 12 bits
    2 : Diviseur de fréquence
    le code est correct mais dans un FPGA il faut eviter de multiplier les horloges et surtout d'utiliser des "ripple clock" car rien ne garanti qu'il y aura un arbre d'horloge disponible pour la router.
    Les affectations concurrentes d'un signal dans un même process c'est légal mais inutile ici
    Donc la bonne solution c'est de générer un signal d'enable qui sera utilisé à la fois pour gérer le diviseur et dans l’étage suivant, le code corrigé
    Code:
    -----------------------DIVISEUR DE FREQUENCES---------------------------------
      process(Clk_50M,raz_n)
        begin
          if(raz_n='0') then
            count   <=1;
            tmp     <='0';
          elsif(Clk_50M'event and Clk_50M='1') then
            if (count = 4999) then
               tmp  <= '1';
            else 
               tmp  <= '0';
            end if;
            if tmp = '1' then
               count <= 1;
            else 
              count  <= count+1;
           end if;
         end if;
       end process;
    3 : le compteur de mesure
    le signal pwm étant asynchrone de l'horloge du FPGA il est indispensable d'effectuer une resynchronisation, il faut rajouter 2 bascules(ff1,ff2) pour faire çà. Si cette resynchronisation n'est pas faite on aura à coup sur un jour ou l'autre un probleme de métastabilité c'est à l'origine de nombreux dysfonctionnements quelquefois gravissimes et c'est très difficile à trouver dans un code complexe.
    Ensuite le process de comptage doit être activé par l'horloge et non par le signal pwm, tel qu’écrit il ne s'active qu'une fois!
    pour finir si tu désires une sortie stable de la valeur alors il faut rajouter un tampon(reg) entre le compteur et la sortie, il faudra générer un signal de chargement.
    tout ceci conduit à:
    Code:
      ---------------------------COUNTER----------------------------------------
       process(tmp,raz_n) begin
         if raz_n = '0' then
             temp<= (others=>'0');
             reg<=(others=>'0');
             ff1<= '0';resync
             ff2 <= '0';resync
             ff3 <= '0';pour chargement et clear compteur
         elsif(Clk_50M'event and Clk_50M='1') then
             -- resynchronisation
             ff1<= in_pwm_compas ;
             ff2<= ff1;
             -- comptage
             if ff2 = '1' and ff3 = '0' then -- front montant du signal pwm
                temp <= (others=>'0');
             elsif ff2 = '1' and tmp= '1' then --etat haut
                 temp <= temp + 1;
             end if;
             if ff2 = '0' and ff3 = '1' then-- front descendant du signal pwm
                 reg <= temp;
             end if;
          end if;
       end process;
       data_compas <= reg;
    4 : mais il manque encore un étage car il faut soustraire l'offset
    5 : ce code n'est pas optimal car il induit une erreur de mesure d'un cycle du signal tmp , que faudrait il faire pour la supprimer ?
    je te laisse faire et digérer.
    notas :
    lorsque l'on déclare un integer il faut préciser le range sinon on instancie 32 bits, normalement le compilo fait le ménage mais c'est un bonne habitude à prendre.

    elsif(Clk_50M'event and Clk_50M='1') then s’écrit de façon plus lisible elsif rising_edge(Clk_50M) then
    attention au packages utilisés et à l'usage de l'arithmétique sur des objets de type std_logic_vector
    dans un process synchrone il suffit de placer l'horloge et le reset (si c'est le seul signal asynchrone activant le process) dans la liste de sensibilité, les autres signaux d'entrée seront "vus" par l'activation due à l'horloge.

    JR
    Dernière modification par jiherve ; 04/10/2020 à 17h04.
    l'électronique c'est pas du vaudou!

  10. #9
    Leond95

    Re : aide exercice vhdl

    Merci de ces précieuses corrections et conseils, je vais essayer de finir ce bloc.

  11. #10
    Leond95

    Re : aide exercice vhdl

    salut jiherve,

    est ce que tu peux me donner des pistes pour réaliser le bloc pour soustraire l'offset, car j'ai pas trouvé de solutions sur google.

    merci
    p.s : est ce qu'il faut créer une variable qu'on le nomme offset et vers la fin du process on le met à 0

  12. #11
    jiherve

    Re : aide exercice vhdl

    Bonsoir,
    comme ton offset est constant il suffit de faire suivre le compteur par un soustracteur, donc utiliser le signe moins dans une équation, le compilateur fera le reste.
    mais encore attention à l'arithmétique avec les std_logic_vector.
    Code:
    data_compas <= reg - offset
    normalement on peut tout faire avec :
    Code:
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    mais au lieu d’écrire :
    Code:
    temp <= temp + 1
    il faudra écrire:
    Code:
    temp <= std_logic_vector(unsigned( temp) + 1)
    et donc la soustraction de l'offset se fera par
    Code:
    data_compas <= std_logic_vector(unsigned(reg) -offset)
    offset ayant été déclaré par:
    Code:
    constant offset  : unsigned := 12345;
    JR
    l'électronique c'est pas du vaudou!

Discussions similaires

  1. [Programmation] Demande d'aide pour un exercice VHDL
    Par draco801 dans le forum Électronique
    Réponses: 3
    Dernier message: 04/11/2018, 19h52
  2. VHDL exercice 7 segments
    Par Chico2000 dans le forum Électronique
    Réponses: 14
    Dernier message: 03/11/2014, 09h38
  3. VHDL : besoin d'aide !
    Par invite1af3caff dans le forum Logiciel - Software - Open Source
    Réponses: 3
    Dernier message: 08/05/2009, 11h11
  4. Aide VHDL matrice
    Par invite8206142f dans le forum Électronique
    Réponses: 3
    Dernier message: 03/04/2009, 02h36
  5. Aide pour compteur en VHDL
    Par inviteca665004 dans le forum Électronique
    Réponses: 12
    Dernier message: 10/03/2008, 21h32
Découvrez nos comparatifs produits sur l'informatique et les technologies.