Nézzük meg az egyik leggyakrabban használt "D" tárolónak (1. ábra) a különböző VHDL nyelvi megvalósítási lehetőségeit.
1. ábra A megvalósítandó D flipflop schema-ja
Először megnézzük a D flipflop-nak (DFF) azt a megvalósítását, amely nem tartalmaz "CLR" (reset) jelet. Azután kitérünk a szinkron és az aszinkron törlési lehetőségekre is.
D flipflop törlés nékül
Először a bemeneteket és a kimenteket bit típusként ábrázoljuk. Fontos tudni, hogy a bit típussal csak logikai 0-t és 1-et tudunk megjeleníteni. Ez a tulajdonság befolyásolni fogja a szimulációs eredményeinket.
Először a "CLR" bemenetet nem valósítjuk meg, csak a "D"-t és a "CLK"-t. Ennek a D flipflop-nak a VHDL kódja látható itt:
entity dff1 is
port(D, CLK : in bit;
Q, nQ : out bit);
end dff1;
architecture BEH of dff1 is
begin
process(D, CLK)
begin
if CLK'event and CLK = '1' then
Q <= D;
nQ <= not(D);
else
null;
end if;
end process;
end BEH;
Az órajel felfutó élére beolvassuk a "D" bemenetet és a kimenetre (Q) tesszük, illetve a bemenet negáltját a kimenet negáltjára (nQ) írjuk ki.
Itt látható a szimulációs környezete az első D flipflop (dff1.vhd) megvalósításnak. A szimulálandó VHDL kódot komponensként illesztjük be a tesztkörnyezetünkbe.
entity dff1sim is
port(Q, nQ : out bit);
end dff1sim;
architecture BEH of dff1sim is
component dff1 is
port(D, CLK : in bit;
Q, nQ : out bit);
end component;
signal SD, SCLK : bit;
begin
nev: dff1 port map (SD, SCLK, Q, nQ);
process
begin
SD <= '0';
SCLK <= '0';
wait for 20 ns;
SCLK <= '1';
wait for 10 ns;
SCLK <= '0';
wait for 30 ns;
end process;
end BEH;
Fordítsuk le ezt a VHDL kódot is (Compile / Compile file 'dff1sim.vhd'), majd válasszuk ki, a projektünk melyik file-át kívánjuk szimulálni (2. ábra).
2. ábra A szimulációs file kiválasztása
A 3. ábrán látjuk a szimulált D flipflopunk működését. Vegyük észre, hogy 0-20 ns között a ponált és a negált kimenet állapota megegyezik!
3. ábra A szimulációs eredmény
Ez természetesen hibás, de a hiba oka nem a VHDL kódunk architektúrális leírásában keresendő, hanem típusban. A "bit" típus nem alkalmas már erre a szimulációra, hiszen 0-20 ns között ismeretlen kimenetet kellett volna kapnunk, mert az órajel (CLK) csak a 20 ns-ban vált állapotot. Viszont a "bit" típussal csak logikai nulla és logikai egy jeleníthető meg.
Keressünk egy másik típust!
Ezért módosítsuk az első VHDL kódunkat, a bit típust írjuk át std_logic-ra. Ez a kód (dff2.vhd) látható itt :
LIBRARY IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dff2 is
port(D, CLK : in std_logic;
Q, nQ : out std_logic);
end dff2;
architecture BEH of dff2 is
begin
process(D, CLK)
begin
if CLK'event and CLK = '1' then
Q <= D;
nQ <= not(D);
else
null;
end if;
end process;
end BEH;
Látható az, hogy a típuson kívül mást nem változtattunk meg. Fontos, hogy az "std_logic" használatához elengedthetlen az IEEE könyvtár meghivatkozása és az IEEE.STD_LOGIC_1164.ALL csomag használata. Ezt kiemelten jelöltük az előző VHDL kódban.
Természetesen a szimulációs környezetben is módosítani kell a típust :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dff2sim is
port(Q, nQ : out std_logic);
end dff2sim;
architecture BEH of dff2sim is
component dff2 is
port(D, CLK : in std_logic;
Q, nQ : out std_logic);
end component;
signal SD, SCLK : std_logic;
begin
nev: dff2 port map (SD, SCLK, Q, nQ);
process
begin
SD <= '0';
SCLK <= '0';
wait for 20 ns;
SCLK <= '1';
wait for 10 ns;
SCLK <= '0';
wait for 30 ns;
end process;
end BEH;
Indítsuk újra a szimulációt, válasszuk ki a dff2sim file-t (4. ábra)
4. ábra A dff2sim file kiválasztása
Az új szimulációs eredményt mutatja az 5. ábra.
5. ábra A helyes szimulációs eredmény
A tesztvektor nem változott meg, ezért a kimeneti eredmény megegyezik azzal a különbséggel, hogy 0-20 ns között a kimenet már az "ismeretlen" állapotot veszi fel. Az órajel felfutásakor kapuzzuk be a "D" bemenet értékét (ez most logikai nulla) is.
Idáig logikai nulla volt a bemeneten a resetelés miatt, az órajel felfutásakor is ezt jelenítettük meg a kimeneten.
D flipflop aszinkron törléssel
Változtassuk meg a VHDL kódunkat, tegyünk be az entitásban egy "CLR" bemenetet, illetve módosítsuk az arhitektúrális leírást is (dff3.vhd) :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dff3 is
port(D, CLK, CLR : in std_logic;
Q, nQ : out std_logic);
end dff3;
architecture BEH of dff3 is
begin
process(D, CLK)
begin
if CLR = '1' then
Q <= '0';
nQ <= '1';
else
if CLK'event and CLK = '1' then
Q <= D;
nQ <= not(D);
else
null;
end if;
end if;
end process;
end BEH;
Helyezzük bele komponensként az előző VHDL kódot ebbe a tesztkörnyezetbe (dff3sim.vhd) :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dff3sim is
port(Q, nQ : out std_logic);
end dff3sim;
architecture BEH of dff3sim is
component dff3 is
port(D, CLK, CLR : in std_logic;
Q, nQ : out std_logic);
end component;
signal SD, SCLK, SCLR : std_logic;
begin
nev: dff3 port map (SD, SCLK, SCLR, Q, nQ);
process
begin
SD <= '0';
SCLK <= '0';
SCLR <= '0';
wait for 20 ns;
SCLR <= '1';
wait for 10 ns;
SCLR <= '0';
wait for 20 ns;
SCLK <= '1';
SD <= '1';
wait for 10 ns;
SCLK <= '0';
SD <= '0';
wait for 30 ns;
end process;
end BEH;
Válasszuk ki a "dff3sim.vhd" file-t a szimulációhoz (6. ábra).
6. ábra A CLR bemenetet tartalmazó VHDL file kiválasztása
Futtassuk most a szimulációt újra. Látható, hogy amikor a "CLR" jel 0->1-be megy, akkor az eddig ismeretlen állapotú kimenetek (Q, nQ) logikai 0-ba, illetve 1-be kerülnek. Amikor a "D" és a "CLK" bemenetekre logikai 1-et adunk, akkor kimenet (Q) logikai 1-be kerül, és ezt az állapotot egészen a következő "CLR=1" értékig meg is őrzi (7. ábra).
7. ábra Aszinkron törlés
D flipflop szinkron törléssel
Készítsünk most egy szinkron törlésű D flipflop-ot. Ehhez csak az architektúrális részt kell módosítanunk, elvileg a következőképpen :
process(D, CLK, CLR)
begin
if CLK'event and CLK = '1' and CLR = '1' then
Q <= '0';
nQ <= '1';
elsif CLK'event and CLK = '1' and CLR = '0' then
Q <= D;
nQ <= not(D);
else
null;
end if;
end process;
A "CLK" és a "CLR" egy feltételvizsgálatban kaptak helyet, amely nem szerencsés, például a régebbi Xilinx fordítók nem kezelik ezt a megoldást.
Módosítsuk ezért a következőképpen a korábbi VHDL kódunkat (dff4jo.vhd) :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dff4jo is
port(D, CLK, CLR : in std_logic;
Q, nQ : out std_logic);
end dff4jo;
architecture BEH of dff4jo is
begin
process(D, CLK, CLR)
begin
if CLK'event and CLK = '1' then
if CLR = '1' then
Q <= '0';
nQ <= '1';
else
Q <= D;
nQ <= not(D);
end if;
else
null;
end if;
end process;
end BEH;
A "CLK" állapotát vizsgáló feltételes szerkezetbe betettük a "CLR"-t ellenőrző if-es szerkezetet, véleményünk szerint ez átláthatóbb, minden fejlesztőszoftver által fordítható kódot kaptunk. Helyezzük ezt a VHDL kódot (dff4jo.vhd) a korábbi szimulációs környezetünkbe (amellyel az aszinkron DFF-et vizsgáltuk) a következőképpen :
architecture BEH of dff3sim is
component dff4jo is
port(D, CLK, CLR : in std_logic;
Q, nQ : out std_logic);
end component;
signal SD, SCLK, SCLR : std_logic;
begin
nev: dff4jo port map (SD, SCLK, SCLR, Q, nQ);
Látható a szimulációs eredményen, hogy hiába jelent meg a CLR-en a 0->1->0 átmenet (50 ns), a kimenetek továbbra is ismeretlenek maradtak, ezek csak akkor változnak meg, amikor az órajel megváltozik (8. ábra).
8. ábra Szinkron törlésű DFF aszinkron tesztkörnyezetben
Azért kaptuk ezt a szimulációs eredményt, mert az aszinkron D flipflop tesztvektorát tettük a szinkron DFF-re. Viszont a törlőjel nincs szinkronizálva az órajelre.
Ezért módosítsuk most a tesztkornyezetünket (szimulációs vektort) a következők szerint :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dff4sim is
port(Q, nQ : out std_logic);
end dff4sim;
architecture BEH of dff4sim is
component dff4jo is
port(D, CLK, CLR : in std_logic;
Q, nQ : out std_logic);
end component;
signal SD, SCLK, SCLR : std_logic;
begin
nev: dff4jo port map (SD, SCLK, SCLR, Q, nQ);
process
begin
SD <= '0';
SCLK <= '0';
SCLR <= '0';
wait for 20 ns;
SCLR <= '1';
SCLK <= '1';
wait for 10 ns;
SCLR <= '0';
SCLK <= '0';
wait for 10 ns;
SCLK <= '1';
SD <= '1';
wait for 10 ns;
SCLK <= '0';
SD <= '0';
wait for 30 ns;
end process;
end BEH;
Válasszuk ki a "dff4sim.vhd" file-t a szimulációhoz (9, ábra) és futtassuk újra a szimulátort.
9. ábra A "dff4sim.vhd" kiválasztása
A szinkron törlésű DFF szimulációs eredményén jól látható, hogy amikor a "CLR" és a "CLK" egyszerre megy fel logikai 1-be, akkor a kimenet törlésre kerül, megszűnik az ismeretlen állapot (10. ábra).
10. ábra A szinkron törlésű D flipflip új szimulációja
Elkészítünk most VHDL nyelven egy PWM modult. Természetesen digitális úton állítunk elő PWM jelet.. . . .
Készítünk VHDL nyelven most egy programozható szélességű multiplexert, amelyet azután elhelyezünk egy Spartan 6-os FPGA-ban. A bemenet (és a kiválasztó jel) szélessége paraméteresen állítható be a fordítás előtt.. . . .
Készítünk VHDL nyelven most egy programozható szélességű multiplexert, amelyet azután elhelyezünk egy Spartan 6-os FPGA-ban. A bemenet (és a kiválasztó jel) szélessége paraméteresen állítható be a fordítás előtt.. . . .