loader
Foto

Trace használata a VHDL nyelvben

A VHDL hardverleíró nyelv a mai napig közkedvelt a digitális áramkörtervezők világában. Használata kényelmes. A trace használata néha elengedhetetlen, amikor az adott digitális architektúrát késleltetés szempontjából akarjuk vizsgálni. Ezért ebben a bejegyzésben a trace használatának az alapjait tekintjük át egy egyszerű példa segítségével. Egy soros összeadót vizsgálunk meg.

Szeretnénk összeadni két tetszőleges bitszélességú számot (A, B). Ezt soros vagy párhuzamos felépítésű összedóval tudjuk megtenni.
A soros összeadó teljes összeadókból (Full Adder, FA) épül fel. A teljes összeadó (1. ábra) három bit bemenettel (a, b, ci) rendelkezik, amelyek szimmetrikusak.

kep
1. ábra   Teljes összeadó egyik lehetséges ábrázolása
 

A teljes összeadó struktúrális VHDL kódja látható itt.

library IEEE;
use ieee.std_logic_1164.all;

entity fa is
    port(A, B, Ci : in std_logic;
        S, Cout : out std_logic);
end fa;

architecture str of fa is
begin

    S <= (A xor B xor Ci);
    Cout <= (A and B) or (A and Ci) or (B and Ci);

end str;

 

Ez a VHDL kód nem alkalmas arra, hogy time szimulációt hajtsunk végre rajta, ezért egészítsük ki ennek megfelelően. Tételezzük fel, hogy a kapukésleltetés legrosszabb esetben 0.5 ns mind a két kimenetnél. (Az "S" kimenet előállításához egy egyszintű hálózat kell, de a carry kimenethez egy kétszintű kell. Mind a két kimenethez 0.5 ns-ot rendeltünk, feltételezve, hogy a két kimenet késleltetése megegyezik.)

library IEEE;
use ieee.std_logic_1164.all;

entity fa is
    port(A, B, Ci : in std_logic;
        S, Cout : out std_logic);
end fa;

architecture str of fa is
begin

    S <= ((A xor B xor Ci)) after 0.5 ns;
    Cout <= ((A and B) or (A and Ci) or (B and Ci)) after 0.5 ns;

end str;

 

Építsünk fel a teljes összeadóból egy 32 bites soros öszeadót (2. ábra)! A teljes összeadó carry kimenetét összekötjük a következő összeadó carry bemenetével. Ezért lesz ez a megoldás soros összeadó.

kep
2. ábra   32 bites soros összeadó felépítése
 

A soros összeadó VHDL kódja látható itt, ez a megoldás paraméteres, azaz, az entitásban a generic-nél tudjuk kényelmesen megváltoztatni a soros összeadó szélességét. Látható, hogy a teljes összeadót komponensként használtuk fel.

library IEEE;
use ieee.std_logic_1164.all;

entity addsoros is
    generic(m : integer := 32);
    port(A, B : in std_logic_vector(m-1 downto 0);
        Cin : in std_logic;
        S : out std_logic_vector(m-1 downto 0);
        Cout : out std_logic);
end addsoros;

architecture str of addsoros is
    component fa is
        port(A, B, Ci : in std_logic;
        S, Cout : out std_logic);
    end component;
signal    temp : std_logic_vector(m downto 0);
begin
    temp(0) <= Cin;
    cimke: for i in 0 to m-1 generate
        nev: fa port map(A(i), B(i), temp(i), S(i), temp(i+1));
    end generate;
        
    Cout <= temp(m);
end str;

 

Soros összeadó architektúrális leírásában, a változtatható bitszélesség miatt, generate ciklust használtunk fel.

Ezt a soros összeadót megvalósító VHDL kódot fogjuk szimulálni úgy, hogy trace-t használunk. Ezáltal szinte bitszinten tudjuk vizsgálni az "A" és a "B" értékeinek összeadásának folyamatát. Látni fogjuk a szimulációs eredményeknél, hogy a soros összeadó hátránya a bitszélességtől függő időkésleltetés, illetve ennek a késleltetésnek az értéke ráadásul nem becsülhető meg, mert függ a bemenetek értékétől.

A trace-hez használnunk kell az std.textio.vhd csomagot, ezért hozzáadjuk az "addsorostrace.vhd" file-hoz.

Az "A" és a "B" signal-ok deklarálásakor megadjuk a szimulációhoz szükséges értékeket. Először legyen "AAAAAAAA" és "55555555". Ezek egymásnak negáltjai.

A szimulálandó "addsoros.vhd" file-t most nem komponensként hivatkoztuk meg az architecture-begin között, hanem egy most másik megoldást mutatunk be. Az "adder: entity trace.addsoros ...." segítségével tudunk szimulációs környezetet kiépíteni, nem kell component-et használnuk. A "trace" a workspace neve, ezt meg kell változtatnuk, ha a projektünk neve nem "trace".

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_textio.all;
use STD.textio.all;

entity addsorostrace is
end addsorostrace;

architecture trace of addsorostrace is
signal    A:    std_logic_vector(31 downto 0) := x"AAAAAAAA";
signal    B:    std_logic_vector(31 downto 0) := x"55555555";
signal    Cin:  std_logic := '0';
signal    Cout: std_logic;            
signal    S:  std_logic_vector(31 downto 0);
begin

    adder: entity trace.addsoros port map(A, B, Cin, S, Cout);

    process(S)
    variable sor : line;
    alias swrite is write [line, string, side, width] ;
    begin
        swrite(sor, "S = ");
        write(sor, S);
        swrite(sor, ",  ido=");
        write(sor, now);
        writeline(output, sor);
    end process;

end trace;

 

A process-ben iratjuk ki a konzolra szövegesen a szimuláció eredményét, ezt az "swrite"-ok segítségével formázzuk is.

Szimuláljuk le az addsoros.vhd file-t, és a következő eredményt kapjuk.

kep
3. ábra   "AAAAAAAA" és az "55555555" összeadásának szimulációjának eredménye
 

Változtassuk meg a "55555555" szimulációs vektort, egyezzen meg a másik értékével. Szimuláljuk újra a soros összeadót megvalósító VHDL file-t (4. ábra).

kep
4. ábra   Két "AAAAAAAA" szám összeadása
 

Nézzük meg a szimulációs eredményt a konzolon is (5. ábra)!

kep
5. ábra   A szimuláció "szöveges" megjelenítése
 

Látjuk az új szimulációs eredményből, hogy már nem szükséges 16 ns a két szám összeadásához, legrosszabb esetben (0.5 ns felő becslés), max 1 ns kell két 32 bites szám összeadásához.



Egyéb cikkek

További cikkeink ebben a témakörben

Régebbi cikkeink

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.. . . .