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.
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
beginS <= (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
beginS <= ((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ó.
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);
beginadder: 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.
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).
4. ábra Két "AAAAAAAA" szám összeadása
Nézzük meg a szimulációs eredményt a konzolon is (5. ábra)!
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.
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.. . . .