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

Constanten en generieke kaart gebruiken in VHDL

Het maken van modules is een geweldige manier om code opnieuw te gebruiken, maar vaak heb je dezelfde module nodig met kleinere variaties in je ontwerp. Dit is waar generieke geneesmiddelen en de generieke kaart voor zijn. Hiermee kunt u bepaalde delen van de module configureerbaar maken tijdens het compileren.

Constanten worden gebruikt als we willen voorkomen dat we dezelfde waarde steeds opnieuw moeten typen. Ze kunnen worden gebruikt voor het definiëren van bitbreedten van signaalvectoren tijdens het compileren, en ze kunnen zelfs worden toegewezen aan generieke constanten. Constanten kunnen overal in de code worden gebruikt in plaats van signalen en variabelen, maar hun waarden kunnen na het compileren niet worden gewijzigd.

Deze blogpost maakt deel uit van de serie Basic VHDL Tutorials.

In de vorige tutorial hebben we een multiplexermodule met 4 ingangen gemaakt met een busbreedte van 8 bits. Maar wat als we ook een vergelijkbare MUX nodig hebben met een andere busbreedte? Is de enige oplossing om de code in een nieuwe module te kopiëren en plakken en de cijfers te wijzigen?

Gelukkig niet.

Het is mogelijk om constanten in VHDL te maken met behulp van deze syntaxis:
constant <constant_name> : <type> := <value>;

Constanten kunnen samen met signalen worden gedeclareerd in het declaratieve deel van een VHDL-bestand, of ze kunnen samen met variabelen in een proces worden gedeclareerd.

Constanten kunnen via de entiteit in een module worden doorgegeven met behulp van de generic trefwoord. De syntaxis voor het maken van een entiteit voor een module die generieke constanten accepteert, is:
entity <entity_name> is
generic(
    <entity_constant_name> : <type> [:= default_value];
    ...
);
port(
    <entity_signal_name> : in|out|inout <type>;
    ...
);
end entity;

De syntaxis voor het instantiëren van een generieke module in een ander VHDL-bestand is:
<label> : entity <library_name>.<entity_name>(<architecture_name>)
generic map(
    <entity_constant_name> => <value_or_constant>,
    ...
)
port map(
    <entity_signal_name> => <local_signal_name>,
    ...
);

Oefening

In deze video-tutorial leren we hoe we een module met generieke constanten in VHDL kunnen maken en instantiëren:

De definitieve code voor de generieke MUX testbench :

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T16_GenericMapTb is
end entity;

architecture sim of T16_GenericMapTb is

    constant DataWidth : integer := 8;

    signal Sig1 : signed(DataWidth-1 downto 0) := x"AA";
    signal Sig2 : signed(DataWidth-1 downto 0) := x"BB";
    signal Sig3 : signed(DataWidth-1 downto 0) := x"CC";
    signal Sig4 : signed(DataWidth-1 downto 0) := x"DD";

    signal Sel : signed(1 downto 0) := (others => '0');

    signal Output : signed(DataWidth-1 downto 0);

begin

    -- An Instance of T16_GenericMux with architecture rtl
    i_Mux1 : entity work.T16_GenericMux(rtl)
    generic map(DataWidth => DataWidth)
    port map(
        Sel    => Sel,
        Sig1   => Sig1,
        Sig2   => Sig2,
        Sig3   => Sig3,
        Sig4   => Sig4,
        Output => Output);

    -- Testbench process
    process is
    begin
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= "UU";
        wait;
    end process;

end architecture;

De definitieve code voor de generieke MUX module :

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T16_GenericMux is
generic(DataWidth : integer);
port(
    -- Inputs
    Sig1 : in signed(DataWidth-1 downto 0);
    Sig2 : in signed(DataWidth-1 downto 0);
    Sig3 : in signed(DataWidth-1 downto 0);
    Sig4 : in signed(DataWidth-1 downto 0);

    Sel  : in signed(1 downto 0);

    -- Outputs
    Output : out signed(DataWidth-1 downto 0));
end entity;

architecture rtl of T16_GenericMux is
begin

    process(Sel, Sig1, Sig2, Sig3, Sig4) is
    begin

        case Sel is
            when "00" =>
                Output <= Sig1;
            when "01" =>
                Output <= Sig2;
            when "10" =>
                Output <= Sig3;
            when "11" =>
                Output <= Sig4;
            when others => -- 'U', 'X', '-', etc.
                Output <= (others => 'X');
        end case;

    end process;

end architecture;

Het golfvormvenster in ModelSim nadat we op run hebben gedrukt en ingezoomd op de tijdlijn:

Analyse

We hebben een MUX-module gemaakt met een configureerbare busbreedte. Nu wordt de busbreedte op slechts één plaats gespecificeerd, in het testbench-bestand. We kunnen het gemakkelijk veranderen om een ​​MUX met een andere busbreedte te creëren.

Als we de golfvorm vergelijken met die uit de vorige zelfstudie, kunnen we zien dat het gedrag identiek is. Dit komt omdat we het gedrag van de code helemaal niet hebben veranderd.

Afhaalmaaltijden

  • Constanten kunnen worden gebruikt om hardcoderende waarden op meerdere plaatsen te vermijden
  • Algemene middelen kunnen worden gebruikt om modules flexibeler te maken

Ga naar de volgende tutorial »


VHDL

  1. Een procedure gebruiken in een proces in VHDL
  2. Een onzuivere functie gebruiken in VHDL
  3. Een functie gebruiken in VHDL
  4. Een procedure gebruiken in VHDL
  5. Constanten en generieke kaart gebruiken in VHDL
  6. Hoe Port Map-instantiatie te gebruiken in VHDL
  7. Een Case-When-statement gebruiken in VHDL
  8. Ondertekend en niet-ondertekend gebruiken in VHDL
  9. Voorwaardelijke instructies gebruiken in VHDL:If-Then-Elsif-Else
  10. Hoe een VHDL-simulator en -editor gratis te installeren
  11. PIC18 Microcontroller:wat het is en hoe het te gebruiken?