Programowalne układy logiczne Układy synchroniczne Szymon Acedański Marcin Peczarski Instytut Informatyki Uniwersytetu Warszawskiego 26 października 2015
Co to jest układ sekwencyjny? W układzie sekwencyjnym, w przeciwieństwie do kombinacyjnego, stan wyjść zależy nie tylko od aktualnego stanu wejść, ale również od stanu wejść w przeszłości. Układ sekwencyjny posiada pamięć stan wewnętrzny. Układ sekwencyjny powstaje przez dodanie sprzężenia zwrotnego do układu kombinacyjnego. wejścia układ kombinacyjny wyjścia
Prosty układ sekwencyjny
Układy sekwencyjne asynchroniczne Zmiana stanu wewnętrznego może być wywołana zmianą stanu na dowolnym wejściu. Projektowanie jest bardzo trudne: konieczność eliminowania hazardów i wyścigów, niedostatek narzędzi automatyzujących ten proces. Synteza w FPGA wymaga wiedzy daleko wykraczającej poza zakres tego wykładu: bardzo trudno jest zapewnić stabilną pracę w pełnym zakresie częstotliwości sygnałów wejściowych, niewielka zmiana projektu może zmienić czasy propagacji sygnałów i doprowadzić do hazardu, standardowe narzędzia dostarczane przez producentów FPGA nie wspomagają syntezy układów asynchronicznych, krytyczne fragmenty układu trzeba projektować ręcznie.
Układy sekwencyjne synchroniczne Ma wyróżnione wejście zegarowe. Zmiana stanu wewnętrznego może nastąpić tylko podczas zmiany poziomu sygnału zegarowego, na jego zboczu narastającym lub opadającym. Projektowanie układów synchronicznych jest dużo prostsze niż asynchronicznych wystarczy zapewnić, aby wszystkie hazardy wywołane zmianą poziomu sygnału zegarowego zakończyły się przed kolejną jego zmianą. Obecnie wszystkie duże układy cyfrowe, w tym mikroprocesory, projektuje się jako układy synchroniczne. Uważa się, że układy synchroniczne są wolniejsze, pobierają więcej energii i generują więcej zakłóceń elektromagnetycznych niż układy asynchroniczne.
Automat Moore a Stan wyjść jest funkcją jedynie stanu wewnętrznego. wej. układ kombinacyjny wyznaczający następny stan rejestr stanu układ kombinacyjny sterujący wyjściami wyj. zegar
Automat Mealy ego Stan wyjść jest funkcją aktualnego stanu wejść i stanu wewnętrznego. wej. układ kombinacyjny wyznaczający następny stan rejestr stanu układ kombinacyjny sterujący wyjściami wyj. zegar
Rejestr stanu Na wyjściach jest pamiętany stan, który był na wejściach podczas ostatniego zbocza zegarowego. Sygnały na wejściach muszą być stabilne przez czas zmiany poziomu sygnału zegarowego (ang. rise or fall time) oraz przed i po zboczu zegarowym przez czas ustalania (ang. setup time), podtrzymania (ang. hold time). t SETUP t HOLD 90% 50% 10% t RISE
Przerzutnik D Rejestr stanu buduje się zwykle z przerzutników D wyzwalanych zboczem (ang. D flip flop). D S Q R Q Przedstawiony na rysunku przerzutnik ma wejście danych D, wejście zegarowe wyzwalane zboczem narastającym, wyjście Q oraz wyjście zanegowane Q. Ma też asynchroniczne wejście zerujące R (ang. reset) i ustawiające S (ang. set), używane tylko do inicjowania układu, czyli do ustalenia początkowego stanu wewnętrznego.
Przerzutnik D Przerzutnik musi być zaprojektowany jako układ asynchroniczny, w którym wejście zegarowe jest traktowane jako zwykłe wejście asynchroniczne. Gotowego przerzutnika można używać jako czarnej skrzynki, której wnętrza nie musimy znać, wystarczy tylko poznać tablicę stanów. R S D C Q Q H L X X H L L H X X L H L L X X H H H H L L H H H H H L H H X X Q Q H H X Q Q
Synteza układów sekwencyjnych w FPGA Układy FPGA zawierają gotowe przerzutniki wyzwalane zboczem sygnału zegarowego, co umożliwia poprawne zaprojektowanie układu synchronicznego. W HDL nie musimy jawnie specyfikować przerzutników kompilator wstawi je automatycznie, gdy wykryje, że układ posiada stan wewnętrzny. Niestety kompilator czasem wstawi przerzutnik również wtedy, gdy naszą intencją nie było wprowadzenie stanu, ale np. zapomnieliśmy dodać klauzuli else lub when others.
Przykład synchronicznego układu sekwencyjnego w VHDL Nadal twierdzimy, że najlepiej jest poznawać język programowania na przykładach. Zobaczmy zatem kolejny przykład dzielnik częstotliwości. Dzielnik częstotliwości zapewne będzie się pojawiał jako komponent w każdym projekcie. Dzielnik ma asynchroniczne wejście zerujące układy z pamięcią wymagają zerowania (ang. reset) po włączeniu zasilania. Następnie obejrzyjmy wynik jego symulacji. Pliki znajdują się pod adresem http://www.mimuw.edu.pl/~marpe/pul/hdl/w4_divider.
Zadanie 2 (1) Zaimplementuj układ sekwencyjny realizujący stoper. Układ ma parametr n, będący liczbą całkowitą nieujemną. Układ ma n-bitowe wejście input, wejście zegara clk o częstotliwości 1 khz, wejścia sterujące rst, toggle oraz dir (wszystkie synchroniczne), n-bitowe wyjście output, wyjście active, wyjście ovf.
Zadanie 2 (2) Stoper mierzy czas w ms. Bieżące wskazanie czasu powinno być wyprowadzane na wyjście output (jako liczba n-bitowa). Jeśli na wejściu rst jest stan niski, to zmiana stanu z niskiego na wysoki na wejściu toggle powoduje na przemian uruchomienie bądź zatrzymanie stopera Jeśli na wejściu dir jest stan wysoki, stoper odlicza do góry, a gdy stan niski w dół. Podanie na wejście rst stanu wysokiego zatrzymuje stoper i ustawia na wyjściu 0, gdy na wejściu dir jest stan wysoki, a wartości z wejścia input w p.p. Jeśli wskazywana wartość miałaby przekroczyć bieżąca wartość z wejścia input lub spaść poniżej zera, stoper się zatrzymuje i przestaje reagować na sygnał toggle, a sygnał ovf jest ustawiany na wysoki. Sygnał ovf powraca do stanu niskiego, gdy na wejściu rst pojawia się stan wysoki.
Zadanie 2 (3) Wyjście active ma stan wysoki, jeśli stoper jest uruchomiony, a niski w p.p. Po włączeniu zasilania stoper powinien być zatrzymany, a na wyjściu output powinna być ustawiona wartość 0, gdy na wejściu dir jest stan wysoki, a wartości z wejścia input, gdy na wejściu dir jest stan niski.
Zadanie 2 (4) Zaimplementuj jednostkę demonstrującą użycie powyższego układu z parametrem n = 16. Jako wejść input(15 downto 9) użyj przełączników bistabilnych sw(7 downto 1). Na wejściach input(8 downto 0) ustal stan niski. Wartość na wyjściu output wyświetl na wyświetlaczu 7-segmentowym (w dziesiątkach milisekund). Druga kropka (od lewej) powinna być zawsze zaświecona, a ostatnia odzwierciedlać stan wyjścia active. Do wygenerowania lub wyprowadzenia pozostałych sygnałów użyj: led(7) ovf, btn(3) rst, btn(0) toggle, sw(0) dir. Do wygenerowania sygnału zegarowego użyj sygnału MCLK (50 MHz), który jest podłączony na płytce do pinu B8 układu.
Zadanie 2 (5) Napisz testy jednostkowe dla zaimplementowanych jednostek projektowych i uruchom je w modelu behawioralnym (w innych modelach możemy uruchamiać jedynie główną jednostkę projektową). Wszystkie wejścia powinny być próbkowane, a wyjścia ustawiane, na zboczu narastającym sygnału zegarowego. Czas na oddanie rozwiązania do 24 listopada 2015 r.
Konwersja liczby dwójkowej na dziesiętną Liczby dziesiętne najchętniej zapisujemy jako BCD, np. 12 zapisujemy jako 0001 0010. Chcemy skonwertować liczbę dwójkową b 3 b 2 b 1 b 0 na liczbę BCD d 3 d 2 d 1 d 0 j 3 j 2 j 1 j 0. Zauważmy, że j 0 = b 0 oraz d 3 = d 2 = d 1 = 0. Jeśli b 3 b 2 b 1 < 5, to d 0 j 3 j 2 j 1 = 0b 3 b 2 b 1, a w przeciwnym przypadku d 0 j 3 j 2 j 1 = 0b 3 b 2 b 1 + 0011.
Algorytm Double Dabble Operacja Setki Dzies. Jedn. Liczba dwójkowa wejście 10000110 przesuń 1 0000110 przesuń 10 000110 przesuń 100 00110 przesuń 1000 0110 dodaj 3 1011 0110 przesuń 1 0110 110 dodaj 3 1 1001 110 przesuń 11 0011 10 przesuń 110 0111 0 dodaj 3 1001 1010 0 przesuń 1 0011 0100 BCD 1 3 4
Moduł Add3 a 3 a 2 a 1 a 0 Add3 y 3 y 2 y 1 y 0 Na wejściu zawsze a 3 a 2 a 1 a 0 < 10. Jeśli a 3 a 2 a 1 a 0 < 5, to y 3 y 2 y 1 y 0 = a 3 a 2 a 1 a 0, a w przeciwnym przypadku y 3 y 2 y 1 y 0 = a 3 a 2 a 1 a 0 + 0011. Na wyjściu zawsze y 2 y 1 y 0 1 < 10.
Algorytm Double Dabble w wersji kombinacyjnej Konwersja liczby n-bitowej wymaga n 3 warstw modułów Add3. 0 0 b 7 b 6 b 5 b 4 b 3 b 2 b 1 b 0 Add3 Add3 Add3 Add3 Add3 Add3 Add3 s 1 s 0 d 3 d 2 d 1 d 0 j 3 j 2 j 1 j 0
Algorytm Double Dabble w wersji sekwencyjnej Konwersja liczby n-bitowej wymaga n 3 taktów zegara. W każdym takcie przepuszczamy dane przez moduły Add3, a potem przesuwamy je o jeden bit w lewo, z prawej strony wsuwamy kolejny bit danych wejściowych. Na początku potrzebne jest przesunięcie o 3 bity w lewo, ale w sprzęcie to nic nie kosztuje pierwszy krok obliczeń wygląda tak: 0 0 0 0 0 0 0 0 0b n 1 b n 2 b n 3 b n 4 Add3 Add3 Add3