Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> VHDL

Voorbeeld van verklaring debouncer genereren

De Genereer-instructie in VHDL kan automatisch een codeblok dupliceren naar sluitingen met identieke signalen, processen en instanties. Het is een for-lus voor de architectuurregio die geketende processen of module-instanties kan maken.

In tegenstelling tot een reguliere for-lus, die alleen in een proces of een subprogramma kan bestaan, wordt de instructie Genereer direct in het architectuurgebied van het VHDL-bestand geplaatst. Wanneer het samen met generieke geneesmiddelen wordt gebruikt, wordt het een krachtig hulpmiddel voor het ontwerpen van aanpasbare VHDL-modules die hergebruik in verschillende ontwerpen mogelijk maken.

Opdrachtsyntaxis genereren

De syntaxis van de instructie genereren is als volgt:

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

De onderdelen tussen vierkante haken zijn optioneel. U kunt dus het declaratieve gebied en de begin . weglaten trefwoord als u geen lokale objecten wilt declareren. Het tijdelijke aanduiding vertegenwoordigt een standaard geheeltallig bereik met behulp van to of downto .

One-bit switch debouncer

Voordat we beginnen met het genereren van de instructie, zal ik een eenvoudige module presenteren die we in dit artikel als voorbeeld zullen gebruiken. Het is een debouncer die een enkele schakelaaringang kan debouncen.

Om het bruikbaar te maken voor elke kloksnelheid, heb ik een generieke invoer toegevoegd met de naam timeout_cycles . Deze constante specificeert hoeveel klokcycli de time-out zal zijn nadat de schakelaaringang verandert. De debouncer negeert elke extra wijziging in de schakelwaarde tijdens de time-outperiode.

De onderstaande lijst toont de entiteit van de debouncer module. Er is een springerige schakelaar invoer, en dan is er de schone switch_debounced uitvoer.

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;

De debouncer-module vertrouwt op een integer-teller om de time-outperiode te bereiken. De lengte van de teller signaal volgt de generieke constante. Dat is wat de time-outduur die is opgegeven tijdens het starten doet.

Omdat we de waarde van de switch_debounced . moeten lezen uitvoer intern, heb ik een schaduwsignaal met de naam debounced verklaard , die we in plaats daarvan zullen gebruiken. Dat is een schonere oplossing dan de andere optie, namelijk het instellen van inout modus op switch_debounce in de entiteit.

Ten slotte implementeren we het debouncing-gedrag in één proces, zoals weergegeven in de onderstaande code.

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;

De onderstaande golfvorm toont een simulatie van de debounce module in ModelSim. We kunnen zien dat de switch_debounced uitgang volgt de schakelaar invoer, maar het negeert het onmiddellijke stuitergedrag na de eerste wijziging - het debouncet het signaal.

Gebruik het onderstaande formulier om de VHDL-code uit dit artikel te downloaden. Wanneer u uw e-mailadres invoert, ontvangt u een Zip-bestand met het hele ModelSim-project met testbanken en een quick-run script. U ontvangt toekomstige updates van VHDLwhiz en u kunt zich op elk moment afmelden.

Genereer for loop met instanties

Om een ​​debouncer te maken voor een reeks switches, gaan we een Genereer-instructie gebruiken om meerdere exemplaren van onze one-bit debouncer-module te maken.

De onderstaande lijst toont de entiteit van onze nieuwe array- of vectordebouncer-module. Het is vergelijkbaar met de one-bit debouncer, maar er is een extra generieke invoer:switch_count . Het geeft aan hoeveel exemplaren van de debouncer-module moeten worden gemaakt. Er zou er een moeten zijn voor elke schakelaar.

Verder heb ik de input en output van de schakelaar hernoemd naar de meervoudsversies van het woord, en het zijn nu vectoren in plaats van enkele bits.

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;

In de architectuur is het tijd om het statement Genereer te gebruiken. Het werkt als een gewone for-lus, alleen met het woord "genereren" dat het woord "loop" vervangt. Maar in tegenstelling tot een gewone for-lus, kan het module-instantiaties bevatten.

De for-lus wordt tijdens het compileren uitgevoerd en genereert voor elke iteratie één exemplaar van de debouncer-module. Maar omdat de "i"-constante voor elke iteratie anders zal zijn, kunnen we deze gebruiken om de in- en uitgangen van de debouncers toe te wijzen aan individuele bits op de schakelvectoren, zoals hieronder weergegeven.

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;

Merk op dat het optioneel is om de Genereer-instructie te labelen, maar het kan verstandig zijn om dit te doen. Het label verschijnt in de simulatorhiërarchie en het syntheselogboek, waardoor het gemakkelijker is om de specifieke instantie te identificeren bij het debuggen.

De onderstaande golfvorm toont een simulatie van de vectordebouncer. We kunnen zien dat het label "MY_GEN" hier opnieuw verschijnt, met indexen toegevoegd voor elk van de acht debouncer-instanties.

Deze testbank verandert alleen de ingang van schakelaar nummer 3, dat is wat je ziet in de golfvorm en waarom ik alleen de groep MY_GEN(3) heb uitgebreid.

U kunt dit voorbeeld snel op uw computer uitvoeren als ModelSim is geïnstalleerd. Gebruik het onderstaande formulier om de broncode en het ModelSim-project te downloaden!

Genereer voor lus bevattende processen

In het laatste voorbeeld van dit artikel zullen we een Genereer-instructie gebruiken om een ​​reeks identieke processen te maken. In plaats van exemplaren van de one-bit debouncer-module te maken, heb ik de VHDL-code eruit gehaald. De entiteit is hetzelfde als in het vorige voorbeeld, en het gedrag ook, maar de implementatie is anders.

We kunnen zien dat ik het DEBOUNCE_PROC-proces binnen de Genereer-instructie heb verplaatst en het enigszins heb gewijzigd in de onderstaande code. Deze keer verklaar ik twee lokale signalen in de instructie Genereer:debounced en teller .

Elke iteratie van de for-lus zal een extra kopie van de signalen en het proces creëren. Het gebruik van deze signaalnamen binnen het proces zal verwijzen naar degene die binnen het bereik van die specifieke lusiteratie vallen.

Ten slotte wijs ik de debounced . toe std_logic signaal naar het juiste bit van de switches_debounced module-uitvoer met behulp van een gelijktijdige instructie boven het proces.

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;

Ik heb de simulatiegolfvorm weggelaten omdat deze er precies hetzelfde uitziet als in het vorige voorbeeld met behulp van module-instantiatie. Het gedrag is identiek.

Via onderstaand formulier kunt u alle code downloaden. Wanneer u uw e-mailadres invoert, schrijft u zich in voor updates van VHDLwhiz. Maar maak je geen zorgen, er is een afmeldlink in elke e-mail die ik stuur.

Laat hieronder een reactie achter als je nog een handige applicatie hebt om uitspraken te genereren om te delen! ?


VHDL

  1. Procedureverklaring - VHDL-voorbeeld
  2. Records - VHDL-voorbeeld
  3. Variabelen - VHDL-voorbeeld
  4. Circuit met een schakelaar
  5. Commuterende diode
  6. Analyse-opties
  7. Schakeltypes
  8. C# switch-instructie
  9. C# break-instructie
  10. C# doorgaan Verklaring
  11. C++ Switch Case Statement met VOORBEELD