WebElektronika

Aritmetikai egység megvalósítása VHDL nyelven

person access_time 2016.01.15.
Az FPGA-kban megvalósított beágyazott rendszerek szinte kivétel nélkül tartalmaznak valamilyen aritmetikai egységet. Ezért most mi is bemutatunk egy lehetséges megvalósítást. Az alkalmazásunk érdekessége, hogy std_logic típusú a bemenet, de az aritmetikai műveletek megvalósításánál egész típusként használjuk fel az operandusokat. Tehát ennél a példánál konverziókat alkalmazunk.


Az aritmetikai egységünk a négy alapművelet (osztás, szorzá, kivonás, összeadás) elvégzésre képes. Az std_logic típus használata miatt kényelmes ezeknek a műveleteknek az elvégzése, de az osztás művelet megvalósítása nehézségekbe ütközik.
Ezért -megkerülve az osztás megvalósítását- konverziót alkalmazunk, az az, az std_logic típusból egész (integer) típust készítünk a to_integer(unsigned()) függvény segítségével. Ehhez szükséges az ieee.numeric_std csomag. 

A következő VHDL kód úgy készült el, hogy az aritmetika egység két bemenetének szélessége változtatható. Erre szinte szükség is van, hiszen ma a mikrovezérlők világában már nem ritka a 32 bites architektúra, de már hallani 64 bitesről is, de még a 8 bitesek is használatban vannak a fejlesztőknél.

Tehát a két bemenet (A, B) szélessége (m) változtatható, a kimenetet pedig a szorzás miatt 2*m szélességű.

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

entity alu1 is
    generic(m : integer := 8);
    port(A, B : in std_logic_vector(m-1 downto 0);
        SEL : in std_logic_vector(1 downto 0);
        KI : out std_logic_vector(2*m - 1 downto 0));
end alu1;

architecture BEH of alu1 is
signal    SA, SB, temp : integer;
begin

    SA <= to_integer(unsigned(A));
    SB <= to_integer(unsigned(B));
    
    process(A, B, SEL, temp)
    begin
        if SEL = "00" then
            temp <= SA + SB;
        elsif SEL = "01" then
            temp <= SA - SB;
        elsif SEL = "10" then
            temp <= SA * SB;
        else
            temp <= SA / SB;
        end if;
    end process;
    
    KI <= std_logic_vector(to_unsigned(temp, m*2));

end BEH;

 

A SEL bemenet segítségével tudjuk kiválasztani az alkalmazandó műveletet, ehhez if-es szerkezetet használunk. Négy feltételes szerkezet található a VHDL nyelvben, az if-et viszont csak process-ben tudjuk használni.

A konverziók miatt (std_logic -> integer, illetve integer -> std_logic) megadunk három jelet (SA, SB, temp) is. Az SA-ban "tároljuk el" az "A" bemenet konvertált értékét, az SA-ban a "B"-t, illetve az átmeneti eredményt (pl.: osztás) a temp-ben. A temp-ből, mely egész típus, kell készítenünk std_logic-ot, mert az entitásban a kimenet std_logic típus. 

Az elkészült aritmetikai egységünk szimulációs környezetének a VHDL kódja látható a következő részben. A projekt neve a webelektronika

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

entity alu1sim is
    generic(m : integer := 8);
    port(KI : out std_logic_vector(2*m - 1 downto 0));
end alu1sim;

architecture SIM of alu1sim is
signal    SA, SB : std_logic_vector(m-1 downto 0);
signal    SSEL : std_logic_vector(1 downto 0);
begin

    nev: entity webelektronika.alu1 port map(SA, SB, SSEL, KI);
    
    process
    begin
        for i in 0 to 3 loop
            SA <= std_logic_vector(to_unsigned(20, m));
            SB <= std_logic_vector(to_unsigned(3, m));
            SSEL <= std_logic_vector(to_unsigned(i, 2));
            wait for 10 ns;
        end loop;
    end process;

end SIM;

 

A process-ben találjuk a for ciklust, 0 és 3 között változik a for-nak a ciklusváltozója, Az operandusok értékeit (20, 3) nem változtatjuk, csak a műveleteket. Látható, hogy az ALU tesztkörnyezete is úgy készült el, hogy könnyen változtatható meg az aritmetikai egység adatszélessége. A szimulációs eredményt a következő ábra mutatja.

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

Implementáljuk most egy Spartan 6-os FPGA-ban ennek az aritmetikai egységnek a megvalósítását! Először az adatszélesség 8 bit. Az realizálás eredménye a 2. ábrán látható.

kep
2. ábra   Az implementált 8 bites ALU
 

Módosítsuk most a generic-ben a adatszélességet 32 bitesre és fordítsuk le újra a projektünket. A 3 ábrán láthatjuk, hogy a Spartan 6-os FPGA-ban jelentősen megnövekedett a felhasznált slice-ok száma.

kep
3. ábra   Az implementált 32 bites aritmetikai egység