WebElektronika

Programozható szélességű demultiplexer megvalósítása VHDL nyelven

person access_time 2017.10.03.
Megvalósítunk most egy programozható szélességű demultiplexert. Látni fogjuk, hogy a megvalósítás nem annyira egyszerű, kénytelenek vagyunk std_logic_vector típus használata esetén alkalmazni egy processt.


Korábban megnéztük a programozható szélességű multiplexer viselkedésszintű megvalósítását. Most ennek a digitáis alapárakörnek az "inverzét", a demultiplexer VHDL kódját készítjük el.

A demultiplexernek egy skalár (BE), illetve egy vektor (SEL) bemenete van. A megvalósítandó áramkörnek -ellentétben a multiplexerrel- vektorkimenete van.

A programozható szélességű demultiplexer VHDL kódja látható itt:

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

entity demuxprog is
          generic(m : integer := 3);
          port(BE : in std_logic;
                    SEL : in std_logic_vector(m-1 downto 0);
                    Y : out std_logic_vector(2**m-1 downto 0));
end demuxprog;

architecture BEH of demuxprog is
begin

          Y(to_integer(unsigned(SEL))) <= BE;

          -- process(BE, SEL)
          -- begin
                    -- Y <= (others => '0');
                    -- Y(to_integer(unsigned(SEL))) <= BE;
          -- end process;

end BEH;

 

Az entitásban szereplő generic-nél (m) adjuk meg a SEL bemeneti vektor szélésségét. Ennek a paraméternek a hatványa fogja a demultiplexer kimeneti szélességét megadni.
A kimeneti vektor adott bitjét kötjük össze a bemenettel a SEL segítségével. A SEL egy std_logic_vector típus, de az Y kimeneti vektor indexe egész típus. Ezért konverziót kell alkalmaznunk. Ehhez használjuk fel az ieee.numeric_std.all csomagban található "to_integer()" függvényt.

Ezután szimuláljuk le az első demultiplexer megvalósítását. Ehhez szükséges írni egy tesztkörnyezetet, amelynek a VHDL kódját látjuk itt:

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

entity demuxprogsim is
          generic(m : integer := 3);
          port(Y : out std_logic_vector(2**m-1 downto 0));
end demuxprogsim;

architecture sim of demuxprogsim is
          component demuxprog is
                    port(BE : in std_logic;
                              SEL : in std_logic_vector(m-1 downto 0);
                              Y : out std_logic_vector(2**m-1 downto 0));
          end component;
signal SBE : std_logic;
signal SSEL : std_logic_vector(m-1 downto 0);
begin

          nev : demuxprog port map(SBE, SSEL, Y);

          process
          begin
                    SBE <= '1';
                    SSEL <= "010";
                    wait for 10 ns;
          end process;

end sim;

 

Szimuláljuk le a tesztkörnyezet segítségével a demultiplexerünk első megoldását. Látjuk a szimulációs eredményből (1. ábra), hogy a kimenet 2. bitje logikai 1-ben van, a többi kimenet állapota ismeretlen. Ha nem std_logic típust alkalmaznánk, hanem bit típust, akkor logikai 0-kat látnánk, de FPGA-s fejlesztéseknél a bit típus nem javasolt.

kep
1. ábra   Szimulációs eredmény
 

Azért kapunk hibás eredményt, mert a kimeneti vektornak csak az egyik bitje kap konkrét értéket, a többi vektorbit értéke ismeretlen. És az std_logic_vector típussal tudunk ábrázolni ismeretlen kimenetet is, ellentétben a bit típussal, amellyel csak logikai 1-et, illetve logikai 0-t.
Ezért a megoldás az, hogy a többi bitnek is adjunk konkrét értéket (logikai 0-t). Azonban a párhuzamos értékadású blokkban nem tudunk egy kimenetre több különböző értéket adni, mert architektúrális blokkban párhuzamos értékadás van.
Ezért nekünk processt kell alkalmaznunk, hiszen itt soros utasításvégrehajtás van. Javítsuk az első VHDL kódunkat a következő részlet szerint:

-- Y(to_integer(unsigned(SEL))) <= BE;

process(BE, SEL)
begin
          Y <= (others => '0');
          ​Y(to_integer(unsigned(SEL))) <= BE;
end process;

 

Az others segítségével a vektorunk minden bitjére logikai 0-t írunk. A következő sorban az Y kimenet adott bitjét rákötjük a bemenetre. A process szenzitív listájában a "BE" és a "SEL" bemenetek találhatók, ezek közül legalább az egyiknek az állapotváltása kell, hogy a process elinduljon.
Szimuláljuk le ismét a demultiplexerünket a tesztkörnyezet segítségével (2. ábra).

kep
2. ábra   Újabb szimulációs eredmény
 

Látható az újabb szimulációs eredményből, hogy a process blokk használata helyes döntésnek bizonyult, hiszen először "lenullázzuk" a kimenetet, majd az aktuális kimenetbitre a SEL segítségével rákötjük a bemenetet.