Programowalne układy logiczne Układy kombinacyjne Szymon Acedański Marcin Peczarski Instytut Informatyki Uniwersytetu Warszawskiego 28 września 2015
Co to jest układ kombinacyjny? Stan wyjść zależy tylko od aktualnego stanu wejść. Układ o n wejściach i m wyjściach opisuje się za pomocą funkcji f : X Y, gdzie X = {0, 1} n, Y = {0, 1} m. Każde wyjście możemy rozważać osobno, opisując je funkcją boolowską f i : X Y, gdzie i {1, 2,..., m}, X = {0, 1} n, Y = {0, 1}.
Synteza układu kombinacyjnego Każdy układ kombinacyjny można zbudować z bramek AND, OR i NOT, gdyż każdą funkcję boolowską można przedstawić w dysjunktywnej postaci normalnej (ang. DNF), np.: (x 1 x 2 ) (x 1 x 3 ). Zatem, korzystając z praw de Morgana, każdy układ kombinacyjny można też zbudować wyłącznie z bramek NAND: (x 1 x 2 ) (x 1 x 3 ). Każdą funkcję boolowską można też przedstawić w koniunktywnej postaci normalnej (ang. CNF), np.: (x 1 x 2 ) (x 1 x 3 ). Zatem każdy układ kombinacyjny można też zbudować wyłącznie z bramek NOR.
Minimalizacja układu kombinacyjnego Formuły boolowskie w postaci normalnej zwykle nie są optymalne. W procesie syntezy układu scalonego dąży się do minimalizacji: liczby bramek, liczby tranzystorów, liczby i długości połączeń, powierzchni układu, czasów propagacji, poboru energii. Problem minimalizacji jest trudny obliczeniowo.
Przykład układu kombinacyjnego Na wykładzie z architektury komputerów omawia się sumator. Przypomnijmy sobie ten fragment wykładu: http://www.mimuw.edu.pl/~marpe/arch/akptc.pdf slajdy 14 do 17.
Impementacja tego przykładu w VHDL Podobno najlepiej jest poznawać język programowania na przykładach. Obejrzyjmy zatem przykład. Następnie zobaczmy, jak napisać test sprawdzający w symulatorze poprawność implementacji. Pliki znajdują się pod adresem http://www.mimuw.edu.pl/~marpe/pul/hdl/w2_adder.
Zadanie 1a Zaimplementuj półsumator, czyli układ o dwóch wejściach 1-bitowych: a i b, i dwóch wyjściach 1-bitowych: s i c, gdzie s jest sumą wartości bitów a i b modulo 2, a c jest przeniesieniem. Wykorzystując półsumator, zaimplementuj układ, który do m-bitowej liczby binarnej dodaje wartość jednego bitu. Wykorzystując układ z poprzeniego punktu, zaimplementuj układ, który ma n-bitowe wejście i m-bitowe wyjście i zlicza, ile bitów na jego wejściu ma wartość jeden. Zaimplementuj układ demonstrujący działanie powyższego układu dla m = 4 i n = 8, wyświetlający na jednej cyfrze wyświetlacza 7-segmentowego, ile przełączników bistabilnych jest włączonych. Czas na oddanie rozwiązania do 27 października 2015 r.
Obsługa wyświetlacza
Obsługa wyświetlacza
Obsługa wyświetlacza entity hex2seg is port(hex: in std_logic_vector(3 downto 0); -- wartość (1 cyfra szesnastkowa) seg: out std_logic_vector(7 downto 0) -- sygnały sterujące diodami wyświetlacza ); end entity hex2seg;
Obsługa wyświetlacza architecture dummy of hex2seg is type seg_descr_type is array (0 to 1) of std_logic_vector(7 downto 0); constant seg_descr: seg_descr_type := (x"c7", x"89"); -- 0 is L, 1 is H begin with hex select seg <= seg_descr(0) when x"0", -- display L seg_descr(1) when others; -- display H end architecture dummy;
Obsługa wyświetlacza entity demo is port(btn: in std_logic_vector(3 downto 0); seg: out std_logic_vector(7 downto 0); an: out std_logic_vector(3 downto 0)); end entity demo; architecture simple of demo is begin btn2seg: entity work.hex2seg port map(btn, seg); an <= "1110"; end architecture simple;
Definicje wyjść w pliku ucf # Basys2 on board 4-digit 7-segment display # # A # --- # F / G / B # --- # E / / C # ---. DP # D # NET "seg<0>" LOC = "L14"; NET "seg<1>" LOC = "H12"; NET "seg<2>" LOC = "N14"; NET "seg<3>" LOC = "N11"; NET "seg<4>" LOC = "P12"; NET "seg<5>" LOC = "L13"; NET "seg<6>" LOC = "M12"; NET "seg<7>" LOC = "N13"; NET "an<0>" LOC = "F12"; NET "an<1>" LOC = "J12"; NET "an<2>" LOC = "M13"; NET "an<3>" LOC = "K14";
Iteracyjne łączenie bloków (1) entity one_bit_box is port(a: in std_logic; b: in std_logic; c: out std_logic; d: out std_logic); end entity one_bit_box; entity m_bit_box is generic(m: natural); port(in_m: in std_logic_vector(m - 1 downto 0); out_m: out std_logic_vector(m - 1 downto 0)); end entity m_bit_box;
Iteracyjne łączenie bloków (2) architecture structural of m_bit_box is signal carry: std_logic_vector(m downto 0); begin m_bit: for i in 0 to m - 1 generate one_bit: entity work.one_bit_box port map(in_m(i), carry(i), out_m(i), carry(i + 1)); end generate m_bit; carry(0) <= 0 ; -- Warning: carry(m) is unconnected. end architecture structural;
Iteracyjne łączenie bloków (3) entity m_n_bit_box is generic(m, n: natural); port(...); end entity m_n_bit_box; architecture structural of m_n_bit_box is... begin m_n_bit: for i in 0 to n - 1 generate m_bit: entity work.m_bit_box generic map(m) port map(...);... end architecture structural;