Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> VHDL

Générer un exemple d'anti-rebond d'instruction

L'instruction generate en VHDL peut automatiquement dupliquer un bloc de code vers des fermetures avec des signaux, des processus et des instances identiques. Il s'agit d'une boucle for pour la région d'architecture qui peut créer des processus chaînés ou des instances de module.

Contrairement à une boucle for normale, qui ne peut exister que dans un processus ou un sous-programme, l'instruction de génération est placée directement dans la région d'architecture du fichier VHDL. Lorsqu'il est utilisé avec des génériques, il devient un outil puissant pour concevoir des modules VHDL personnalisables qui permettent une réutilisation dans toutes les conceptions.

Générer la syntaxe de l'instruction

La syntaxe de l'instruction de génération est la suivante :

[label :] for <constant_name> in <range> generate
  [declarations_local_to_each_loop_iteration]
[begin]
  <processes_and_instantiations>
end generate [label];

Les parties entre crochets sont facultatives. Ainsi, vous pouvez omettre la région déclarative et le begin mot clé si vous ne souhaitez pas déclarer d'objets locaux. La l'espace réservé représente une plage d'entiers standard utilisant to ou downto .

Anti-rebond de commutateur à un bit

Avant de commencer sur l'instruction generate, je vais présenter un module simple que nous utiliserons comme exemple tout au long de cet article. C'est un anti-rebond capable d'anti-rebond d'une seule entrée de commutateur.

Pour le rendre utilisable pour n'importe quelle vitesse d'horloge, j'ai ajouté une entrée générique nommée timeout_cycles . Cette constante spécifie le nombre de cycles d'horloge du délai d'attente après le changement d'entrée du commutateur. L'anti-rebond ignorera toute modification supplémentaire de la valeur du commutateur pendant la période de temporisation.

La liste ci-dessous montre l'entité du anti-rebond module. Il y a un interrupteur rebondissant entrée, puis il y a le propre switch_debounced sortie.

entity debouncer is
  generic (
    timeout_cycles : positive
    );
  port (
    clk : in std_logic;
    rst : in std_logic;
    switch : in std_logic;
    switch_debounced : out std_logic
  );
end debouncer;

Le module anti-rebond s'appuie sur un compteur entier pour atteindre la période de temporisation. La longueur du compteur signal suit la constante générique. C'est ce que fait la durée d'expiration spécifiée lors de l'instanciation.

Parce que nous devons lire la valeur de switch_debounced sortie en interne, j'ai déclaré un signal fantôme nommé debounced , que nous utiliserons à sa place. C'est une solution plus propre que l'autre option, qui consiste à définir inout mode sur switch_debounce dans l'entité.

Enfin, nous implémentons le comportement anti-rebond en un seul processus, comme indiqué dans le code ci-dessous.

architecture rtl of debouncer is

  signal debounced : std_logic;
  signal counter : integer range 0 to timeout_cycles - 1;

begin

  -- Copy internal signal to output
  switch_debounced <= debounced;

  DEBOUNCE_PROC : process(clk)
  begin
    if rising_edge(clk) then
      if rst = '1' then
        counter <= 0;
        debounced <= switch;
        
      else
        
        if counter < timeout_cycles - 1 then
          counter <= counter + 1;
        elsif switch /= debounced then
          counter <= 0;
          debounced <= switch;
        end if;

      end if;
    end if;
  end process;

end architecture;

La forme d'onde ci-dessous montre une simulation du anti-rebond module dans ModelSim. Nous pouvons voir que le switch_debounced la sortie suit le commutateur entrée, mais il ignore le comportement de rebond immédiat après le premier changement - il anti-rebond du signal.

Utilisez le formulaire ci-dessous pour télécharger le code VHDL de cet article. Lorsque vous saisissez votre adresse e-mail, vous recevez un fichier Zip contenant l'intégralité du projet ModelSim avec des bancs d'essai et un script d'exécution rapide. Vous recevrez de futures mises à jour de VHDLwhiz et vous pourrez vous désabonner à tout moment.

Générer une boucle for avec des instanciations

Pour créer un anti-rebond pour un tableau de commutateurs, nous allons utiliser une instruction generate pour créer plusieurs instances de notre module anti-rebond à un bit.

La liste ci-dessous montre l'entité de notre nouveau module anti-rebond de tableau ou de vecteur. C'est similaire à l'anti-rebond à un bit, mais il y a une entrée générique supplémentaire :switch_count . Il spécifie le nombre d'instances du module anti-rebond à créer. Il devrait y en avoir un pour chaque commutateur.

De plus, j'ai renommé l'entrée et la sortie du commutateur aux versions plurielles du mot, et ce sont maintenant des vecteurs au lieu de bits simples.

entity debouncer_gen_inst is
  generic (
    switch_count : positive;
    timeout_cycles : positive
    );
  port (
    clk : in std_logic;
    rst : in std_logic;
    switches : in std_logic_vector(switch_count - 1 downto 0);
    switches_debounced : out std_logic_vector(switch_count - 1 downto 0)
  );
end debouncer_gen_inst;

Dans l'architecture, il est temps d'utiliser l'instruction generate. Cela fonctionne comme une boucle for normale, seulement avec le mot « générer » remplaçant le mot « boucle ». Mais contrairement à une boucle for normale, elle peut contenir des instanciations de modules.

La boucle for s'exécute au moment de la compilation et génère une instance du module anti-rebond pour chaque itération. Mais comme la constante "i" sera différente pour chaque itération, nous pouvons l'utiliser pour mapper les entrées et les sorties des anti-rebonds sur des bits individuels sur les vecteurs de commutation, comme indiqué ci-dessous.

architecture rtl of debouncer_gen_inst is
begin

  MY_GEN : for i in 0 to switch_count - 1 generate

    DEBOUNCER : entity work.debouncer(rtl)
    generic map (
      timeout_cycles => timeout_cycles
    )
    port map (
      clk => clk,
      rst => rst,
      switch => switches(i),
      switch_debounced => switches_debounced(i)
    );

  end generate;

end architecture;

Notez qu'il est facultatif d'étiqueter l'instruction de génération, mais il peut être judicieux de le faire. L'étiquette apparaît dans la hiérarchie du simulateur et le journal de synthèse, ce qui facilite l'identification de l'instance spécifique lors du débogage.

La forme d'onde ci-dessous montre une simulation du vecteur anti-rebond. Nous pouvons voir que l'étiquette "MY_GEN" réapparaît ici, avec des index ajoutés pour chacune des huit instances anti-rebond.

Ce testbench ne change que l'entrée du commutateur numéro 3, c'est ce que vous voyez dans la forme d'onde et c'est pourquoi j'ai développé uniquement le groupe MY_GEN(3).

Vous pouvez rapidement exécuter cet exemple sur votre ordinateur si ModelSim est installé. Utilisez le formulaire ci-dessous pour télécharger le code source et le projet ModelSim !

Générer une boucle for contenant des processus

Dans le dernier exemple de cet article, nous utiliserons une instruction generate pour effectuer une série de processus identiques. Au lieu de créer des instances du module anti-rebond à un bit, j'en ai extrait le code VHDL. L'entité est la même que dans l'exemple précédent, tout comme le comportement, mais l'implémentation est différente.

Nous pouvons voir que j'ai déplacé le processus DEBOUNCE_PROC dans l'instruction de génération et que je l'ai légèrement modifié dans le code ci-dessous. Cette fois, je déclare deux signaux locaux dans l'instruction generate :debounced et contre .

Chaque itération de la boucle for créera une copie supplémentaire des signaux et du processus. L'utilisation de ces noms de signaux dans le processus fera référence à ceux qui sont limités à l'enceinte de cette itération de boucle spécifique.

Enfin, j'attribue le rebondi std_logic signal au bon bit du switches_debounced sortie du module à l'aide d'une instruction concurrente au-dessus du processus.

architecture rtl of debouncer_gen_proc is
begin

  MY_GEN : for i in 0 to switch_count - 1 generate

    signal debounced : std_logic;
    signal counter : integer range 0 to timeout_cycles - 1;

  begin

    switches_debounced(i) <= debounced;

    DEBOUNCE_PROC : process(clk)
    begin
      if rising_edge(clk) then
        if rst = '1' then
          counter <= 0;
          debounced <= switches(i);

        else

          if counter < timeout_cycles - 1 then
            counter <= counter + 1;
          elsif switches(i) /= debounced then
            counter <= 0;
            debounced <= switches(i);
          end if;

        end if;
      end if;
    end process;

  end generate;

end architecture;

J'ai omis la forme d'onde de simulation car elle ressemble exactement à celle de l'exemple précédent utilisant l'instanciation de module. Le comportement est identique.

Vous pouvez télécharger tout le code en utilisant le formulaire ci-dessous. Lorsque vous entrez votre adresse e-mail, vous vous abonnez aux mises à jour de VHDLwhiz. Mais ne vous inquiétez pas, il y a un lien de désabonnement dans chaque e-mail que j'envoie.

Laissez un commentaire ci-dessous si vous avez une autre application utile pour générer des relevés à partager ! ?


VHDL

  1. Instruction de procédure - Exemple VHDL
  2. Enregistrements - Exemple VHDL
  3. Variables - Exemple VHDL
  4. Options d'analyse
  5. Types de commutateur
  6. Instruction de commutateur C #
  7. Instruction de rupture C#
  8. Instruction continue C #
  9. Instruction C++ Switch Case avec EXAMPLE