TC Moduł 13: Różnice pomiędzy wersjami
Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 1: | Linia 1: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd1.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd1.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Projektowanie układów cyfrowych cz. 2. | ||
W niniejszym wykładzie omawiamy projektowanie układów cyfrowych z zastosowaniem języków opisu sprzętu. W poprzednim wykładzie omówiliśmy zasady specyfikacji języka AHDL. Omówienie bardziej rozbudowanych języków HDL np. VHDL lub Verilog jest niemożliwe ze względu na ograniczony zakres wykładu. I dlatego główna część niniejszego wykładu poświęcona będzie specyfikacjom w języku AHDL. Jednak w celu pokazania większych związków ''techniki cyfrowej'' z współczesną ''informatyką'', w dalszej (nieobowiązkowej) części wykładu omawiamy specyfikacje tego samego układu w bardziej zaawansowanych i abstrakcyjnych językach VHDL i Verilog. | |||
|} | |} | ||
Linia 8: | Linia 10: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd2.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd2.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|W niniejszym module przedstawimy proces projektowania układu cyfrowego z użyciem języków opisu sprzętu HDL. Zaprojektujemy układ konwertera liczby binarnej na dwucyfrową liczbę BCD. Działanie algorytmu zostało szczegółowo omówione w module 11, a teraz skupimy się na wyspecyfikowaniu tego układu w wersji behawioralnej. | ||
Działanie układu opisane jest siecią działań i składa się z trzech kroków: wprowadzenia danych, przetwarzania i wypisania danych. | |||
|} | |} | ||
Linia 15: | Linia 20: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd3.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd3.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Konwerter zapiszemy w języku AHDL. Jak już wiemy, każdy projekt musi składać się z co najmniej dwóch sekcji: sekcji interfejsu oraz opisu działania. Tutaj mamy sekcję interfejsu, czyli w języku AHDL sekcję SUBDESIGN. Projekt nazywa się ''bin2bcd''. Sygnałami wejściowymi są: ośmiobitowy wektor ''lb'', za pomocą którego przekazujemy liczbę binarną do konwersji, skalar start – sygnalizujący rozpoczęcie przetwarzania oraz skalar zegar do synchronizacji automatu i przerzutników. Sygnałami wyjściowymi są: ośmiobitowy wektor ''ld'' na którym pojawi się wynik czyli liczba BCD oraz skalar koniec – sygnalizujący moment wystawienia przetworzonej liczby. Dodatkowo, w sekcji zmiennych VARIABLE, zadeklarowane są zmienne zbudowane z przerzutników typu D. W rejestrze ''lda'' i ''ldb'' przechowywane są, odpowiednio, starsza i młodsza cyfra liczby BCD, rejestr ''lb_r'' służy do zapamiętania wejściowej liczby binarnej, rejestr ''lk'' odlicza liczbę kroków, a wyjście koniec jest synchronizowane sygnałem zegarowym. | ||
|} | |} | ||
Linia 22: | Linia 27: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd4.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd4.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Początek drugiej wymaganej sekcji – opisu logiki – otwiera słowo kluczowe BEGIN (a kończy END). Ponieważ opisywany układ jest układem synchronicznym, to do wszystkich wejść przerzutników ''clk'' należy doprowadzić sygnał zegar. Nawiasami okrągłymi zgrupowano wejścia tego samego typu, co umożliwiło skrócony zapis. Jeżeli na wejściu start pojawi się sygnał logiczny „1”, to nastąpi wpisanie liczby binarnej z wejścia ''lb'' do rejestru wewnętrznego ''lb_r'' oraz licznik kroków lk zostanie ustawiony na wartość 8 – tyle potrzebnych jest cykli zegara, aby otrzymać dwie 4-bitowe cyfry liczby BCD. W języku AHDL domyślnymi równaniami dla przerzutników są równania zerujące, stąd nie musimy inicjować rejestrów ''lda'' i ''ldb''. | ||
|} | |} | ||
Linia 29: | Linia 34: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd5.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd5.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Następnie w kolejnych krokach jest dokonywana konwersja na liczbę BCD. Jeżeli spełniony jest warunek ldb >= 5 to następuje zwiększenie zawartości rejestru ''ldb'' o +3 oraz przesunięcie zawartości rejestrów ''lda'' i ''ldb''. Dla tego warunku najstarszy bit ''ldb[3]'' ma zawsze wartość „1”, dlatego wpisujemy bit „1” na najmłodszej pozycji rejestru lda. Można sprawdzić, że dla starszej cyfry lda, nigdy nie zachodzi warunek ''lda'' >= 5, stąd nie pojawia się on w kodzie AHDL. Jeżeli nie jest spełniony warunek ''ldb'' >= 5, to następuje przesunięcie bitowe rejestrów ''ldb'' i ''lda''. W każdym cyklu zegara przesuwana jest zawartość rejestru ''lb_r'' oraz zmniejszany licznik kroków ''lk''. Główna pętla algorytmu wykonywana jest dopóty, dopóki zawartość licznika kroków ''lk'' nie jest równa zero. | ||
|} | |} | ||
Linia 36: | Linia 41: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd6.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd6.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Po ośmiu taktach zegara wyliczone cyfry z rejestrów ''lda'' i ''ldb'' zapisywane są w rejestrze wyjściowym ld, a na wyjściu koniec pojawia się „1”. Gdyby nie było podtrzymania zawartości rejestrów ''lda'' i ''ldb'' (lda[]=lda[]; ldb[]=ldb[];), to jak już było wcześniej wspomniane, kompilator wygenerowałby równania zerujące i stracilibyśmy wyliczoną liczbę. | ||
|} | |} | ||
Linia 43: | Linia 48: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd7.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd7.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Ze względu na swoją złożoność urządzenia cyfrowe muszą być projektowane w sposób hierarchiczny. Polega to na wyodrębnieniu w projektowanym urządzeniu części składowych realizujących pewne jednostkowe funkcje w taki sposób, aby po połączeniu ich w całość były realizowane zadania projektowanego urządzenia. Następnie część tak wyodrębnionych podprojektów jest realizowana z wykorzystaniem gotowych makrofunkcji bibliotecznych, rdzeni projektowych – modułów IPCore lub modułów zrealizowanych wcześniej przez projektanta (system reuse). W rezultacie jedynie niektóre części składowe projektu muszą być projektowane przez użytkownika jako nowe, oddzielne moduły. Podział projektowanego urządzenia na części składowe umożliwia bardziej efektywną realizację całości, gdyż moduły składowe, z założenia prostsze w swej budowie, są łatwiejsze do zaprojektowania, optymalizacji i weryfikacji. Moduły z niższego poziomu hierarchii mogą być dalej dzielone na mniejsze części w zależności od potrzeb i koncepcji projektanta. Po stworzeniu wszystkich części składowych urządzenia i ich przetestowaniu użytkownik tworzy projekt poprzez połączenie tych części w całość. | ||
|} | |} | ||
Linia 50: | Linia 55: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd8.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd8.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Hierarchia już zrealizowanego w systemie Quartus układu cyfrowego, pokazuje realizację schematu blokowego układu pokazanego na poprzedniej planszy. Układ operacyjny konwertera składa się z ośmiu modułów: czterech rejestrów ''R1, R2, R3, R4,'' licznika ''LK'', sumatora ''S'', komparatora ''K'' i multipleksera ''M''. W module układu sterującego US opisano główny automat wraz z liniami sterującymi do modułu operacyjnego ''UO''. | ||
|} | |} | ||
Linia 57: | Linia 62: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd9.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd9.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Pokazana jest specyfikacja najmniejszym składowych w projekcie: modułów kombinacyjnych, sumatora, komparatora i multipleksera, oraz modułów synchronicznych, tutaj programowalny rejestr z funkcją ładowania ''load'' i zmniejszania zawartości ''dec''. | ||
|} | |} | ||
Linia 64: | Linia 69: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd10.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd10.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Na planszy pokazano przykładową realizację pozostałych rejestrów, z wykorzystaniem konstrukcji CASE lub IF..ELSE. Każdy z tych rejestrów ma nieco inną funkcję. Pokazuje to możliwości języka opisu sprzętu – jego elastyczność, analogicznie jak w językach programowania. | ||
|} | |} | ||
Linia 71: | Linia 76: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd11.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd11.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Mając już składowe elementy, można opisać moduł operacyjny ''UO''. Na początku należy poinformować kompilator z jakich modułów bibliotecznych będziemy korzystać, czyli należy podać deklaracje funkcji zapisane w zbiorach z rozszerzeniem ''inc – include file''. Zawartość przykładowego pliku deklaracji pokazano na planszy dla modułu komparatora ''k.inc''. W sekcji VARIABLE deklarujemy zmienne typu makrofunkcja, na przykład: zmienna komp jest typu ''k''. | ||
|} | |} | ||
Linia 78: | Linia 83: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd12.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd12.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|W sekcji logiki układu operacyjnego następuje konkretyzacja czyli użycie zadeklarowanych wcześniej zmiennych typu makrofunkcja. Zmienną taką możemy porównać do struktury w językach programowania, gdzie do pól tej struktury dostajemy się poprzez odwołanie kropkowe. W językach HDL pola makrofunkcji nazywane są portami. Dzięki zastosowaniu łączenia sygnałów za pomocą funkcji konkatenacji, możliwy jest zwięzły i krótki zapis połączeń pomiędzy modułami składowymi. Na przykład, zapis ''rej1.(a[], s[]) = (lb[], s_[1..0])''; mówi, że do portów ''a'' i ''s'' zmiennej rej1 przyłączone będą odpowiednio wektory ''lb'' i część wektora '''s''_. Należy pamiętać, że kompilator dba jedynie o to, aby wektory składowe lewej strony równania były tej samej sumarycznie długości co suma długości wektorów prawej strony. Projektant musi zwracać szczególną uwagę, na poprawne podłączanie sygnałów, aby zapewnić poprawną pracę układu. | ||
|} | |} | ||
Linia 85: | Linia 90: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd13.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd13.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Moduł układu sterującego jest zrealizowany z użyciem automatu. W sekcji VARIABLE zadeklarowany jest ośmiostanowy automat bez wyspecyfikowania na jakich przerzutnikach ma być realizacja oraz bez podania kodów dla poszczególnych stanów. Kompilator sam zadba o odpowiednią realizację automatu w zależności od zadanych w systemie parametrów oraz od docelowej architektury układu programowalnego. W sekcji logiki zrealizowana jest tablica przejść-wyjść automatu z wykorzystaniem instrukcji CASE. | ||
|} | |} | ||
Linia 92: | Linia 97: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd14.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd14.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Ostatni w hierarchii moduł łączy układ operacyjny i sterujący. Podobnie jak w realizacji behawioralnej, sygnał wyjściowy ''koniec'' jest sygnałem synchronicznym. W okienku Nawigatora Projektu widać nazwę układu, dla którego była przeprowadzona kompilacja EPF10K20RC240-3, co oznacza układ typu FPGA z rodziny Flex10K, o wielkości logicznej 20 (20 tysięcy przeliczeniowych bramek), w katalogowej obudowie RC z 240 wyprowadzeniami i szybkości „3”. | ||
|} | |} | ||
Linia 99: | Linia 104: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd15.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd15.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Złożoność i abstrakcyjność zasad specyfikacji języka VHDL, znacznie różniącego się od stosowanych do tej pory prostych języków HDL dla układów programowalnych powoduje, że jego stosowanie w syntezie układów cyfrowych wymaga od projektanta większego wysiłku. Jednak zaletą jest to, że język ten jest językiem standardowym, a przez to kod HDL jest w większości przenaszalny na inne systemy cyfrowe. Cechą charakterystyczną języka VHDL jest jego ogólność, która wyraża się między innymi tym, że jego podstawowe elementy strukturalne ograniczają się przede wszystkim do obiektów danych, instrukcji i deklaracji, a różnorodność zasad specyfikacji znalazła odbicie w różnorodności instrukcji. W sposób ogólny przedstawiono specyfikację układu konwertera w języku VHDL. Na planszy pokazano deklaracje użytych bibliotek, które umożliwiają użycie obiektów i wykonywaniu operacji na tych obiektach. Poniżej zapisana jest sekcja interfejsu, tutaj nazywana deklaracją jednostki projektowej ENTITY. | ||
|} | |} | ||
Linia 106: | Linia 111: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd16.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd16.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|W bloku architektury ARCHITECTURE jest opisane działanie lub struktura realizowanego układu. Zawiera on część deklaracyjną, w tym przykładzie nie ma, oraz część instrukcyjną, po słowie kluczowym BEGIN. Słowo kluczowe PROCESS jest instrukcją współbieżną, zawierającą instrukcje sekwencyjne. Instrukcja ta jest wykonana, gdy zmieni się wartość sygnału wyspecyfikowanego w liście wrażliwości. Na przykład, instrukcja PROCESS(''zegar'') zostanie wykonana przy zmianie sygnału zegar. Poniżej jest deklaracja zmiennych lokalnych. Należy zwrócić uwagę, iż zmienne deklarowane są dla typu reprezentacji liczb, a nie dla typu kombinacyjnego lub rejestrowego. To czy zmienna będzie realizowała część kombinacyjną czy rejestrową zależy od jej użycia. | ||
|} | |} | ||
Linia 113: | Linia 118: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd17.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd17.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Za pomocą zdefiniowanego w języku VHDL atrybutu EVENT dla sygnału zegar oraz sprawdzeniu stanu logicznego tego sygnału można wyszczególnić tzw. moment charakterystyczny sygnału. W tym przykładzie jest to zbocze narastające sygnału zegarowego czyli zmiana sygnału zegarowego z wartości „0” na „1”. W języku VHDL zmienne należy inicjować. | ||
|} | |} | ||
Linia 120: | Linia 125: | ||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|width="500px" valign="top"|[[Grafika:TC_M13_Slajd18.png|thumb|500px]] | |width="500px" valign="top"|[[Grafika:TC_M13_Slajd18.png|thumb|500px]] | ||
|valign="top"| | |valign="top"|Główna pętla algorytmu jest zrealizowana analogicznie jak w AHDL. Należy zwrócić uwagę, że instrukcja „&” służy do łączenia sygnałów (konkatenacji), a nie jest to operator typu AND. | ||
|} | |} |
Wersja z 01:46, 15 wrz 2006
![]() |
Główna pętla algorytmu jest zrealizowana analogicznie jak w AHDL. Należy zwrócić uwagę, że instrukcja „&” służy do łączenia sygnałów (konkatenacji), a nie jest to operator typu AND. |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |