Vezessük vissza először a kivonást összeadásra. Ha a különbséget (A-B) akarjuk kiszámolni, akkor a kivonandó (negatív) számot adjuk hozzá ahhoz a számhoz (A), amelyből a kivonást szeretnénk elvégezni (1. ábra).
1. ábra Kivonás összeadással
Ahhoz, hogy ezt a kivonást el tudjuk végezni, szükségünk van a "B" komplemensére. Használhatnánk itt egyes vagy akár kettes komplemenst is. Nézzük meg a kettes komplemensképzés lehetőségeit (2. ábra). Képezzük tehát az "A" vektornak (an-1 . . . ai . . . a0) a kettes komplemensét.
Az első megoldás szerint az "A" vektor minden elemét negáljuk, majd az eredményhez hozzáadunk egyet. A második módszer az, hogy az "A" vektor LSB bitjétől haladva a bitek értékeit az első logikai 1-ig változatlanul hagyjuk, a logikai 1-et is, majd azután az MSB bit felé haladva az összes bitet negáljuk (2. ábra).
2. ábra Kettes komplemens előállításának lehetőségei
Látható tehát az, hogy a kettes komplemens előállítása nem nehéz, például az első módszer áramköri "megoldását" mutatja a 3. ábra.
3. ábra Kettes komplemens előállítása telejs összeadókkal és inverterekkel
Ha a teljes összeadó egyik bemenetére (4. ábra) olyan bemenetet teszünk, amelyen a logikai érték lehet negált vagy ponált, akkor olyan áramköri elemet kapunk, amelynek segítségével kivonást vagy összeadást valósítunk meg.
4. ábra Teljes összeadó XOR kapuval
A XOR kapu segítségével tudjuk megvalósítani az összeadást és a kivonás műveletet. Az "M" bemenet segítségével tudjuk kiválasztani az aktuális műveletet.
Több áramköri megoldás terjedt el az összeadásra/kivonásra, mi először a kettes komplemensű megvalósítást tekintjük át.
Az "n" bites soros összeadó/kivonó áramkör felépítését látjuk az 5. ábrán, amelynél a soros átvitelképzés segítségével összekötésre kerültek a teljes összeadók. A teljes összeadó egyik bemenetére csatlakozik a XOR kapu, amellyel ki tudjuk választani az aritmetikai műveletet.
5. ábra Összeadó/kivonó áramkör kettes komplemensképzéssel
Tetszőleges méretű soros összeadó/kivonó áramkör implementálható ezzel a VHDL kóddal, a konkrét értéket a generic-nél állíthatjuk be. Ez az aritmetikai áramkör teljes összeadókból épül fel, ennek az egységnek a VHDL kódja például itt található.
A kettes komplemensű aritmetikai egységnek a VHDL kódjában két "for generate" ciklust találunk, az elsőben az "n" darab XOR kaput valósítjuk meg, a másodiknál a komponenseket kötjük össze.
library IEEE;
use ieee.std_logic_1164.all;
entity addsub2comp is
generic(m : integer := 8);
port(A, B : in std_logic_vector(m-1 downto 0);
MC : in std_logic;
S : out std_logic_vector(m-1 downto 0);
Over : out std_logic);
end addsub2comp;
architecture STR of addsub2comp is
component fa1 is
port(A, B, Cin : in std_logic;
S, Cout : out std_logic);
end component;
signal temp : std_logic_vector(m downto 0);
signal SB : std_logic_vector(m-1 downto 0);
begin
muv: for i in 0 to m-1 generate
SB(i) <= B(i) xor MC;
end generate;
nev: for i in 0 to m-1 generate
valami: fa1 port map(A(i), SB(i), temp(i), S(i), temp(i+1));
end generate;
temp(0) <= MC;
Over <= temp(m) xor temp(m-1);
end STR;
Az összeadó/kivonó aritmetikai áramkör egyes komplemensképzéssel is megvalósítható. Ebben az esetben a "n-1" teljes összeadó carry kimenetét visszacsatoljuk a 0. teljes összeadó carry bemenetére (6. ábra).
6. ábra Soros összeadó/kivonó áramkör egyes komplemensképzéssel
Az egyes komplemensképzéssel rendelkező összeadó/kivonó áramkör VHDL kódja hasonló az előző megoldáshoz.
library IEEE;
use ieee.std_logic_1164.all;
entity addsub1comp is
generic(m : integer := 8);
port(A, B : in std_logic_vector(m-1 downto 0);
MC : in std_logic;
S : out std_logic_vector(m-1 downto 0);
Over : out std_logic);
end addsub1comp;
architecture STR of addsub1comp is
component fa1 is
port(A, B, Cin : in std_logic;
S, Cout : out std_logic);
end component;
signal temp : std_logic_vector(m downto 0);
signal SB : std_logic_vector(m-1 downto 0);
begin
muv: for i in 0 to m-1 generate
SB(i) <= B(i) xor MC;
end generate;
nev: for i in 0 to m-1 generate
valami: fa1 port map(A(i), SB(i), temp(i), S(i), temp(i+1));
end generate;
temp(0) <= temp(m);
Over <= temp(m) xor temp(m-1);
end STR;
Végül szimuláljuk le a kettes komplemensképzéssel rendelkező aritmetikai egységet. Ehhez szükséges egy tesztkörnyezet, amely természetesen tartalmazza a tesztvektorokat is.
Érdekességként, ennél a megoldásnál nem komponensként helyezzük be ebbe a VHDL kódba a tesztelendő áramkört.
library IEEE;
use ieee.std_logic_1164.all;
entity addsub2compsim is
generic(m : integer := 8);
port(S : out std_logic_vector(m-1 downto 0);
Over : out std_logic);
end addsub2compsim;
architecture SIM of addsub2compsim is
signal SA, SB : std_logic_vector(m-1 downto 0);
signal SMC : std_logic;
begin
nev: entity aritmetika.addsub2comp port map(SA, SB, SMC, S, Over);
process
begin
SMC <= '0';
SA <= x"00";
SB <= x"FF";
wait for 10 ns;
SA <= x"01";
wait for 10 ns;
SB <= x"02";
wait for 10 ns;
SA <= x"55";
SB <= x"AA";
wait for 10 ns;
SB <= x"FF";
wait for 10 ns;
SMC <= '1';
wait for 10 ns;
end process;
end SIM;
A szimulációs eredménynél (7. ábra) az "sa", "sb", "s" jelek/port aktuális értékeit decimálisként ábrázoltuk.
7. ábra Ketteskomplemensű arimtetikai áramkör szimulációs eredménye
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.. . . .