Projekt VLSI - szybki przewodnik

Integracja na bardzo dużą skalę (VLSI) to proces tworzenia pliku integrated circuit (IC), łącząc tysiące plików transistorsw jeden chip. VLSI zaczęło się w latach 70. XX wieku, kiedy było złożonesemiconductor i communicationopracowywano technologie. Plikmicroprocessor jest urządzeniem VLSI.

Przed wprowadzeniem technologii VLSI większość układów scalonych miała ograniczony zestaw funkcji, które mogły wykonywać. Naelectronic circuit może składać się z CPU, ROM, RAM i inne glue logic. VLSI pozwala projektantom układów scalonych dodać je wszystkie do jednego układu.

Przemysł elektroniczny osiągnął fenomenalny wzrost w ciągu ostatnich kilku dziesięcioleci, głównie ze względu na szybki postęp w technologiach integracji na dużą skalę i zastosowaniach do projektowania systemów. Wraz z pojawieniem się projektów integracji na bardzo dużą skalę (VLSI), liczba zastosowań układów scalonych (IC) w wysokowydajnych obliczeniach, sterowaniu, telekomunikacji, przetwarzaniu obrazu i wideo oraz elektronice użytkowej rośnie w bardzo szybkim tempie.

Obecne najnowocześniejsze technologie, takie jak wideo o wysokiej rozdzielczości i niskiej przepływności oraz komunikacja komórkowa, zapewniają użytkownikom końcowym niesamowitą liczbę aplikacji, moc obliczeniową i przenośność. Oczekuje się, że ten trend będzie się szybko rozwijał, co będzie miało bardzo ważny wpływ na projektowanie VLSI i projektowanie systemów.

Przepływ projektowy VLSI

Schemat projektowy obwodów IC VLSI pokazano na poniższym rysunku. Poszczególne poziomy projektowania są ponumerowane, a bloki przedstawiają procesy w przepływie projektowania.

Specyfikacje są na pierwszym miejscu, opisują abstrakcyjnie funkcjonalność, interfejs i architekturę cyfrowego obwodu IC, który ma zostać zaprojektowany.

Następnie tworzony jest opis behawioralny, aby przeanalizować projekt pod względem funkcjonalności, wydajności, zgodności z określonymi normami i innymi specyfikacjami.

Opis RTL jest wykonywany za pomocą HDL. Ten opis RTL jest symulowany w celu przetestowania funkcjonalności. Odtąd potrzebujemy pomocy narzędzi EDA.

Opis RTL jest następnie konwertowany na listę sieci na poziomie bramki za pomocą narzędzi do syntezy logicznej. Lista sieci na poziomie gatelevel to opis obwodu pod względem bramek i połączeń między nimi, które są wykonane w taki sposób, aby były zgodne ze specyfikacjami dotyczącymi czasu, mocy i obszaru.

Na koniec tworzony jest fizyczny układ, który zostanie zweryfikowany, a następnie wysłany do produkcji.

Wykres Y.

Wykres Y Gajskiego-Kuhna to model, który zawiera rozważania przy projektowaniu urządzeń półprzewodnikowych.

Trzy domeny wykresu Y Gajskiego-Kuhna znajdują się na osiach promieniowych. Każdą z domen można podzielić na poziomy abstrakcji za pomocą koncentrycznych pierścieni.

Na najwyższym poziomie (pierścień zewnętrzny) rozważamy architekturę chipa; na niższych poziomach (pierścienie wewnętrzne) sukcesywnie dopracowujemy projekt do bardziej szczegółowej realizacji -

Tworzenie opisu strukturalnego na podstawie opisu behawioralnego osiąga się poprzez procesy syntezy wysokiego poziomu lub syntezy logicznej.

Tworzenie opisu fizycznego na podstawie opisu strukturalnego osiąga się poprzez syntezę układu.

Hierarchia projektu - strukturalna

Hierarchia projektu obejmuje zasadę „Dziel i rządź”. To nic innego jak podzielenie zadania na mniejsze zadania, aż do osiągnięcia najprostszego poziomu. Ten proces jest najbardziej odpowiedni, ponieważ ostatnia ewolucja projektu stała się tak prosta, że ​​jego produkcja staje się łatwiejsza.

Możemy zaprojektować dane zadanie w domenie procesu projektowania (behawioralnego, strukturalnego i geometrycznego). Aby to zrozumieć, weźmy przykład projektowania 16-bitowego sumatora, jak pokazano na poniższym rysunku.

Tutaj cały chip 16-bitowego sumatora jest podzielony na cztery moduły 4-bitowych sumatorów. Ponadto, dzieląc 4-bitowy sumator na 1-bitowy lub półsumator. Dodatek 1-bitowy jest najprostszym procesem projektowania, a jego wewnętrzny obwód jest również łatwy do wykonania na chipie. Teraz, łącząc wszystkie cztery ostatnie sumatory, możemy zaprojektować sumator 4-bitowy i idąc dalej, możemy zaprojektować sumator 16-bitowy.

FPGA - Wprowadzenie

Pełna forma FPGA jest "Field Programmable Gate Array”. Zawiera od dziesięciu tysięcy do ponad miliona bramek logicznych z programowalnymi połączeniami. Programowalne połączenia są dostępne dla użytkowników lub projektantów w celu łatwego wykonywania określonych funkcji. Na rysunku pokazano typowy model układu FPGA. Istnieją bloki I / O, które są zaprojektowane i ponumerowane zgodnie z funkcją. Dla każdego modułu kompozycji poziomu logiki sąCLB’s (Configurable Logic Blocks).

CLB wykonuje operację logiczną przekazaną modułowi. Połączenia między CLB i blokami I / O są realizowane za pomocą poziomych kanałów routingu, pionowych kanałów routingu i PSM (programowalnych multiplekserów).

Liczba zawartych w nim CLB decyduje tylko o złożoności FPGA. Funkcjonalność CLB i PSM jest zaprojektowana przez VHDL lub inny język opisu sprzętu. Po zaprogramowaniu CLB i PSM są umieszczane na chipie i łączone ze sobą kanałami routingu.

Zalety

  • To wymaga bardzo małego czasu; począwszy od procesu projektowania do funkcjonalnego chipa.
  • Nie są zaangażowane żadne fizyczne etapy produkcji.
  • Jedyną wadą jest to, że jest kosztowny niż inne style.

Projekt tablicy bramkowej

Plik gate array (GA)zajmuje drugie miejsce po FPGA pod względem możliwości szybkiego prototypowania. Podczas gdy programowanie użytkownika jest ważne dla implementacji projektu układu FPGA, projektowanie i przetwarzanie maski metalowej jest wykorzystywane w przypadku GA. Implementacja macierzy bramkowej wymaga dwuetapowego procesu produkcyjnego.

Pierwsza faza skutkuje tablicą niezatwierdzonych tranzystorów na każdym układzie GA. Te niezaangażowane chipy można przechowywać w celu późniejszego dostosowania, co jest zakończone przez zdefiniowanie metalowych połączeń między tranzystorami macierzy. Modelowanie metalowych połączeń międzykontynentalnych odbywa się pod koniec procesu wytwarzania chipa, tak że czas realizacji może być nadal krótki, od kilku dni do kilku tygodni. Poniższy rysunek przedstawia podstawowe kroki przetwarzania dla implementacji tablicy bramek.

Typowe platformy z tablicami bramek wykorzystują dedykowane obszary zwane kanałami do routingu międzykomórkowego między rzędami lub kolumnami tranzystorów MOS. Upraszczają wzajemne połączenia. Wzorce połączeń, które wykonują podstawowe bramki logiczne, są przechowywane w bibliotece, której można następnie użyć do dostosowania rzędów niezatwierdzonych tranzystorów zgodnie z listą sieci.

W większości nowoczesnych GA do trasowania kanałów używa się wielu warstw metalu. Dzięki zastosowaniu wielu połączonych ze sobą warstw, trasowanie można uzyskać na aktywnych obszarach komórek; dzięki czemu kanały routingu można usunąć, tak jak w układach Sea-of-Gates (SOG). Tutaj cała powierzchnia chipa jest pokryta niezatwierdzonymi tranzystorami nMOS i pMOS. Sąsiednie tranzystory można dostosować za pomocą metalowej maski do tworzenia podstawowych bramek logicznych.

W przypadku routingu międzykomórkowego niektóre niezatwierdzone tranzystory muszą zostać poświęcone. Ten styl projektowania zapewnia większą elastyczność połączeń międzysystemowych i zwykle większą gęstość. Współczynnik wykorzystania wiórów GA jest mierzony przez wykorzystany obszar wióra podzielony przez całkowitą powierzchnię wióra. Jest wyższa niż w FPGA, podobnie jak prędkość chipa.

Standardowa konstrukcja oparta na komórkach

Standardowy projekt oparty na komórkach wymaga opracowania pełnego zestawu masek niestandardowych. Standardowa komórka jest również znana jako polikomórka. W tym podejściu wszystkie powszechnie używane komórki logiczne są opracowywane, charakteryzowane i przechowywane w standardowej bibliotece komórek.

Biblioteka może zawierać kilkaset komórek, w tym inwertery, bramki NAND, bramki NOR, złożone AOI, bramki OAI, zatrzaski typu D i przerzutniki. Każdy typ bramy może być realizowany w kilku wersjach, aby zapewnić odpowiednią zdolność jazdy dla różnych fan-outów. Bramka falownika może mieć rozmiar standardowy, podwójny i poczwórny, aby projektant chipa mógł wybrać odpowiedni rozmiar, aby uzyskać dużą prędkość obwodu i gęstość układu.

Każda komórka jest scharakteryzowana według kilku różnych kategorii charakteryzacji, takich jak

  • Czas opóźnienia a pojemność obciążenia
  • Model symulacyjny obwodu
  • Model symulacji rozrządu
  • Model symulacji uszkodzeń
  • Dane komórkowe dotyczące miejsca i trasy
  • Maskuj dane

W celu automatycznego umieszczania komórek i trasowania, każdy układ komórek jest zaprojektowany ze stałą wysokością, dzięki czemu wiele komórek można ograniczać obok siebie, tworząc wiersze. Szyny zasilające i uziemiające biegną równolegle do górnej i dolnej granicy komórki. Tak więc sąsiednie komórki mają wspólną szynę zasilającą i wspólną szynę uziemiającą. Poniższy rysunek przedstawia plan piętra dla projektu opartego na standardowych ogniwach.

Pełny projekt niestandardowy

W całkowicie niestandardowym projekcie cały projekt maski jest nowy, bez użycia jakiejkolwiek biblioteki. Koszt rozwoju tego stylu projektowania rośnie. W związku z tym koncepcja ponownego wykorzystania projektu staje się sławna ze względu na redukcję czasu cyklu projektowania i kosztów rozwoju.

Najtrudniejszym całkowicie niestandardowym projektem może być konstrukcja komórki pamięci, statyczna lub dynamiczna. W przypadku projektowania układów logicznych dobre negocjacje można uzyskać, stosując kombinację różnych stylów projektowych na tym samym chipie, tj. Komórki standardowe, komórki ścieżki danych iprogrammable logic arrays (PLAs).

Praktycznie projektant wykonuje pełny układ niestandardowy, tj. Geometrię, orientację i położenie każdego tranzystora. Wydajność projektowa jest zwykle bardzo niska; zwykle kilkadziesiąt tranzystorów dziennie, na projektanta. W cyfrowym CMOS VLSI, projektowanie w pełni niestandardowe jest rzadko używane ze względu na wysokie koszty pracy. Te style projektowania obejmują projektowanie produktów o dużej objętości, takich jak chipy pamięci, wysokowydajne mikroprocesory i FPGA.

Komplementarna technologia MOSFET (CMOS) jest obecnie szeroko stosowana do tworzenia obwodów w licznych i zróżnicowanych zastosowaniach. Dzisiejsze komputery, procesory i telefony komórkowe wykorzystują CMOS ze względu na kilka kluczowych zalet. CMOS oferuje niskie rozpraszanie mocy, stosunkowo dużą prędkość, wysokie marginesy szumów w obu stanach i będzie działać w szerokim zakresie napięć źródłowych i wejściowych (pod warunkiem, że napięcie źródła jest stałe)

W przypadku procesów, które omówimy, typem dostępnego tranzystora jest tranzystor polowy typu metal-tlenek-półprzewodnik (MOSFET). Powstają te tranzystoryas a ‘sandwich’składający się z warstwy półprzewodnika, zwykle kawałka lub płytki z pojedynczego kryształu krzemu; warstwa dwutlenku krzemu (tlenek) i warstwa metalu.

Struktura MOSFET-u

Jak pokazano na rysunku, struktura MOS zawiera trzy warstwy -

  • The Metal Gate Electrode

  • The Insulating Oxide Layer (SiO2)

  • P – type Semiconductor (Substrate)

Struktura MOS tworzy kondensator, a bramka i podłoże są jak dwie płytki i warstwa tlenku jako materiał dielektryczny. Grubość materiału dielektrycznego (SiO 2 ) wynosi zwykle od 10 nm do 50 nm. Koncentracją i rozkładem nośników w podłożu można manipulować za pomocą zewnętrznego napięcia przyłożonego do bramki i zacisku podłoża. Teraz, aby zrozumieć strukturę MOS, najpierw rozważ podstawowe właściwości elektryczne podłoża półprzewodnikowego typu P.

Koncentracja nośnika w materiale półprzewodnikowym jest zawsze zgodna z Mass Action Law. Prawo zbiorowych działań jest podane przez -

$$n.p=n_{i}^{2}$$

Gdzie,

  • n to stężenie nośników elektronów

  • p jest nośnikiem koncentracji otworów

  • ni jest wewnętrznym stężeniem nośnika krzemu

Załóżmy teraz, że podłoże jest równomiernie domieszkowany akceptor (boru) stężenie N A . Zatem stężenie elektronów i dziur w podłożu typu p wynosi

$$n_{po}=\frac{n_{i}^{2}}{N_{A}}$$

$$p_{po}=N_{A}$$

Tutaj koncentracja dopingu NAjest (10 15 do 10 16 cm -3 ) większe niż wewnętrzne stężenie ni. Teraz, aby zrozumieć strukturę MOS, rozważ diagram poziomów energetycznych podłoża krzemowego typu p.

Jak pokazano na rysunku, przerwa wzbroniona między pasmem przewodnictwa a pasmem walencyjnym wynosi 1,1 eV. Tutaj potencjał Fermiego Φ F jest różnicą między wewnętrznym poziomem Fermiego (E i ) a poziomem Fermiego (E FP ).

Gdzie poziom Fermiego E F zależy od stężenia domieszki. Potencjał Fermiego Φ F jest różnicą między wewnętrznym poziomem Fermiego (E i ) a poziomem Fermiego (E FP ).

Matematycznie,

$$\Phi_{Fp}=\frac{E_{F}-E_{i}}{q}$$

Potencjalna różnica między pasmem przewodnictwa a wolną przestrzenią nazywa się powinowactwem elektronowym i jest oznaczona przez qx.

Tak więc energia potrzebna do przejścia elektronu z poziomu Fermiego do wolnej przestrzeni nazywa się funkcją pracy (qΦ S ) i jest wyrażona przez

$$q\Phi _{s}=(E_{c}-E_{F})+qx$$

Poniższy rysunek przedstawia schemat pasm energetycznych komponentów tworzących MOS.

Jak pokazano na powyższym rysunku, izolacyjna warstwa SiO 2 ma dużą energetyczną przerwę energetyczną 8eV, a funkcja pracy wynosi 0,95 eV. Brama metalowa ma funkcję pracy 4,1eV. Tutaj funkcje robocze są różne, więc spowoduje spadek napięcia w systemie MOS. Poniższy rysunek przedstawia schemat połączonego pasma energii systemu MOS.

Jak pokazano na tym rysunku, poziom potencjału fermiego metalowej bramki i półprzewodnika (Si) ma ten sam potencjał. Potencjał Fermiego na powierzchni nazywany jest potencjałem powierzchniowym Φ S i jest mniejszy niż potencjał Fermiego Φ F pod względem wielkości.

Działanie MOSFET-u

MOSFET składa się z kondensatora MOS z dwoma złączami pn umieszczonymi w pobliżu obszaru kanału, a obszar ten jest kontrolowany przez napięcie bramki. Aby oba złącza pn były spolaryzowane odwrotnie, potencjał podłoża jest utrzymywany poniżej potencjału pozostałych trzech końcówek.

Jeśli napięcie bramki wzrośnie powyżej napięcia progowego (V GS > V TO ), na powierzchni utworzy się warstwa inwersyjna, a pomiędzy źródłem a drenem utworzy się kanał typu n. Ten kanał typu n przenosi prąd drenu zgodnie z wartością V DS .

Dla różnych wartości V DS , MOSFET może działać w różnych regionach, jak wyjaśniono poniżej.

Region liniowy

Przy V DS = 0, równowaga termiczna istnieje w odwróconym obszarze kanału i prąd drenu I D = 0. Teraz, jeśli zastosowane zostanie małe napięcie drenu, V DS > 0, prąd drenu proporcjonalny do V DS zacznie płynąć od źródła spuścić przez kanał.

Kanał zapewnia ciągłą ścieżkę przepływu prądu od źródła do drenu. Ten tryb działania nosi nazwęlinear region. Widok przekroju n-kanałowego tranzystora MOSFET działającego w obszarze liniowym pokazano na poniższym rysunku.

Na skraju regionu nasycenia

Teraz, jeśli V DS wzrośnie, ładunki w kanale i głębokość kanału zmniejszają się pod koniec odpływu. Dla V DS = V DSAT ładunki w kanale są redukowane do zera, co jest tzwpinch – off point. Widok przekroju n-kanałowego tranzystora MOSFET pracującego na skraju obszaru nasycenia pokazano na poniższym rysunku.

Region nasycenia

Dla V DS > V DSAT , zubożona powierzchnia tworzy się w pobliżu drenu, a poprzez zwiększenie napięcia drenu ten zubożony obszar rozciąga się do źródła.

Ten tryb działania nosi nazwę Saturation region. Elektrony przychodzące od źródła do końca kanału wchodzą do obszaru wyczerpania drenu i przyspieszają w kierunku drenu w silnym polu elektrycznym.

Prąd MOSFET - Charakterystyka napięcia

Aby zrozumieć charakterystykę prądowo-napięciową tranzystora MOSFET, wykonuje się przybliżenie kanału. Bez tego przybliżenia trójwymiarowa analiza systemu MOS staje się złożona. PlikGradual Channel Approximation (GCA) dla charakterystyki prądowo-napięciowej zmniejszy problem analizy.

Stopniowe przybliżanie kanałów (GCA)

Rozważmy przekrój poprzeczny tranzystora MOSFET z kanałem n pracującym w trybie liniowym. Tutaj źródło i podłoże są połączone z ziemią. V S = V, B = 0. bramy - do - źródła (V GS ) i dren - do - źródła napięcia (V DS ) napięcia są parametrami zewnętrzne, które sterują odpływu prądu I D .

Napięcie V GS jest ustawione na napięcie większe niż napięcie progowe V TO , aby utworzyć kanał między źródłem a drenem. Jak pokazano na rysunku, kierunek x jest prostopadły do ​​powierzchni, a kierunek y jest równoległy do ​​powierzchni.

Tutaj y = 0 na końcu źródła, jak pokazano na rysunku. Napięcie kanału w odniesieniu do źródła jest reprezentowane przezVC(Y). Załóżmy, że napięcie progowe VTO jest stałe wzdłuż obszaru kanału, od y = 0 do y = L.Warunek brzegowy dla napięcia kanału V C wynosi -

$$V_{c}\left ( y = 0 \right ) = V_{s} = 0 \,and\,V_{c}\left ( y = L \right ) = V_{DS}$$

Możemy też to założyć

$$V_{GS}\geq V_{TO}$$ i

$$V_{GD} = V_{GS}-V_{DS}\geq V_{TO}$$

Niech Q1 (y) będzie całkowitym ładunkiem ruchomych elektronów w powierzchniowej warstwie inwersyjnej. Ten ładunek elektronu można wyrazić jako -

$$Q1(y)=-C_{ox}.[V_{GS}-V_{C(Y)}-V_{TO}]$$

Poniższy rysunek przedstawia geometrię przestrzenną warstwy inwersyjnej powierzchni i wskazuje jej wymiary. Warstwa inwersyjna zmniejsza się, gdy przechodzimy od drenu do źródła. Teraz, jeśli weźmiemy pod uwagę mały obszar dy długości kanału L, wówczas przyrostowy opór dR oferowany przez ten region można wyrazić jako -

$$dR=-\frac{dy}{w.\mu _{n}.Q1(y)}$$

Tutaj minus wynika z ujemnej polaryzacji Q1 ładowania warstwa inwersji i μ n jest mobilność powierzchnię, która jest stała. Teraz podstawmy wartość Q1 (y) w równaniu dR -

$$dR=-\frac{dy}{w.\mu _{n}.\left \{ -C_{ox}\left [ V_{GS}-V_{C\left ( Y \right )} \right ]-V_{TO} \right \}}$$

$$dR=\frac{dy}{w.\mu _{n}.C_{ox}\left [ V_{GS}-V_{C\left ( Y \right )} \right ]-V_{TO}}$$

Teraz spadek napięcia w małym obszarze dy można podać wzorem

$$dV_{c}=I_{D}.dR$$

Umieść wartość dR w powyższym równaniu

$$dV_{C}=I_{D}.\frac{dy}{w.\mu_{n}.C_{ox}\left [ V_{GS}-V_{C(Y)} \right ]-V_{TO}}$$

$$w.\mu _{n}.C_{ox}\left [ V_{GS}-V_{C(Y)}-V_{TO} \right ].dV_{C}=I_{D}.dy$$

Aby uzyskać ID prądu drenu w całym obszarze kanału, powyższe równanie można scałkować wzdłuż kanału od y = 0 do y = L i napięć V C (y) = 0 do V C (y) = V DS ,

$$C_{ox}.w.\mu _{n}.\int_{V_{c}=0}^{V_{DS}} \left [ V_{GS}-V_{C\left ( Y \right )}-V_{TO} \right ].dV_{C} = \int_{Y=0}^{L}I_{D}.dy$$

$$\frac{C_{ox}.w.\mu _{n}}{2}\left ( 2\left [ V_{GS}-V_{TO} \right ] V_{DS}-V_{DS}^{2}\right ) = I_{D}\left [ L-0 \right ]$$

$$I_{D} = \frac{C_{ox}.\mu _{n}}{2}.\frac{w}{L}\left ( 2\left [ V_{GS}-V_{TO} \right ]V_{DS}-V_{DS}^{2} \right )$$

Dla regionu liniowego V DS <V GS - V TO . Dla obszaru nasycenia wartość V DS jest większa niż (V GS - V TO ). Dlatego dla regionu nasycenia V DS = (V GS - V TO ).

$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{\left [ 2V_{DS} \right ]V_{DS}-V_{DS}^{2}}{L} \right )$$

$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{2V_{DS}^{2}-V_{DS}^{2}}{L} \right )$$

$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{V_{DS}^{2}}{L} \right )$$

$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{\left [ V_{GS}-V_{TO} \right ]^{2}}{L} \right )$$

Falownik jest naprawdę jądrem wszystkich projektów cyfrowych. Po jasnym zrozumieniu jego działania i właściwości projektowanie bardziej skomplikowanych struktur, takich jak bramki NAND, sumatory, mnożniki i mikroprocesory, jest znacznie uproszczone. Zachowanie elektryczne tych złożonych obwodów można prawie całkowicie wyliczyć poprzez ekstrapolację wyników uzyskanych dla falowników.

Analizę falowników można rozszerzyć, aby wyjaśnić zachowanie bardziej złożonych bramek, takich jak NAND, NOR lub XOR, które z kolei stanowią elementy składowe modułów, takich jak mnożniki i procesory. W tym rozdziale skupimy się na jednym wcieleniu bramki falownika, będącej statycznym falownikiem CMOS - lub w skrócie falownikiem CMOS. Jest to z pewnością obecnie najpopularniejszy i dlatego zasługuje na naszą szczególną uwagę.

Zasada działania

Symbol logiczny i tabela prawdy idealnego falownika pokazano na poniższym rysunku. Tutaj A to wejście, a B to odwrócone wyjście reprezentowane przez ich napięcia węzłowe. Korzystając z logiki dodatniej, wartość logiczna logiki 1 jest reprezentowana przez V dd, a logika 0 jest reprezentowana przez 0. V th jest napięciem progowym falownika, które wynosi V dd / 2, gdzie V dd jest napięciem wyjściowym.

Wyjście jest przełączane z 0 na V dd, gdy wejście jest mniejsze niż V th . Tak więc, dla 0 <V w <V th wyjściowy jest równy logicznej 0 wejściowego i V th <V w <V dd jest równa wartości logicznej 1 dla wejścia przetwornicy.

Cechy przedstawione na rysunku są idealne. Uogólnioną strukturę obwodu falownika nMOS pokazano na poniższym rysunku.

Z podanego rysunku widać, że napięcie wejściowe falownika jest równe napięciu bramki do źródła tranzystora nMOS, a napięcie wyjściowe falownika jest równe napięciu drenu do źródła tranzystora nMOS. Źródło napięcia podłoża nMOS jest również nazywane sterownikiem dla tranzystora, który jest uziemiony; więc V SS = 0. Węzeł wyjściowy jest połączony z kondensowaną pojemnością używaną dla VTC.

Rezystancyjny falownik obciążenia

Podstawową strukturę rezystancyjnego falownika obciążenia pokazano na poniższym rysunku. W tym przypadku jako tranzystor sterujący działa wzmacniacz typu nMOS. Obciążenia składa się prostą liniową rezystor R L . Zasilanie układu jest U DD i pobór prądu, że D jest równa obciążenia prądowego I R .

Działanie obwodu

Gdy napięcie wejściowe tranzystora sterownika jest mniejsze niż napięcie progowe V TH (V in <V TH ), tranzystor sterownika znajduje się w obszarze odcięcia i nie przewodzi prądu. Zatem spadek napięcia na rezystorze obciążenia wynosi ZERO, a napięcie wyjściowe jest równe V DD . Teraz, gdy napięcie wejściowe dalej rośnie, tranzystor sterownika zacznie przewodzić niezerowy prąd i nMOS przejdzie w obszar nasycenia.

Matematycznie,

$$I_{D} = \frac{K_{n}}{2}\left [ V_{GS}-V_{TO} \right ]^{2}$$

Zwiększając dalej napięcie wejściowe, tranzystor sterujący wejdzie w obszar liniowy, a wyjście tranzystora sterującego zmniejszy się.

$$I_{D} = \frac{K_{n}}{2}2\left [ V_{GS}-V_{TO} \right ]V_{DS}-V_{DS}^{2}$$

VTC falownika obciążenia rezystancyjnego, pokazane poniżej, wskazuje tryb pracy tranzystora sterownika i punkty napięciowe.

Falownik z obciążeniem MOSFET typu N.

Główną zaletą stosowania tranzystora MOSFET jako urządzenia obciążającego jest to, że obszar krzemu zajmowany przez tranzystor jest mniejszy niż obszar zajmowany przez obciążenie rezystancyjne. Tutaj MOSFET jest obciążeniem aktywnym, a falownik z aktywnym obciążeniem zapewnia lepszą wydajność niż falownik z obciążeniem rezystancyjnym.

Zwiększenie obciążenia NMOS

Rysunek przedstawia dwa falowniki z dodatkowym urządzeniem obciążającym. Tranzystor obciążający może działać w obszarze nasycenia lub w obszarze liniowym, w zależności od napięcia polaryzacji przyłożonego do jego zacisku bramki. Na rys. 1 przedstawiono nasycony falownik obciążenia wzmocnionego. (za). To wymaga pojedynczego napięcia zasilania i prosty sposób wytwarzania i tak V OH jest ograniczony do V DD - V , T .

Liniowy falownik wzmacniający obciążenie pokazano na rys. (b). Zawsze działa w regionie liniowym; więc poziom V OH jest równy V DD .

Liniowy falownik obciążenia ma wyższy margines szumów w porównaniu z nasyconym falownikiem wzmacniającym. Jednak wadą falownika ze wzmocnieniem liniowym jest to, że wymaga dwóch oddzielnych zasilaczy, a oba obwody mają duże straty mocy. Dlatego falowniki wzmacniające nie są używane w żadnych aplikacjach cyfrowych na dużą skalę.

Wyczerpanie obciążenia NMOS

Wady falownika zwiększającego obciążenie można przezwyciężyć za pomocą falownika zubożonego obciążenia. W porównaniu z falownikiem wzmacniającym, falownik obciążenia zubożonego wymaga kilku dodatkowych kroków produkcyjnych w celu implantacji kanału w celu dostosowania napięcia progowego obciążenia.

Zaletami inwertera obciążenia wyczerpującego są - ostre przejście VTC, lepszy margines szumów, pojedynczy zasilacz i mniejszy całkowity obszar układu.

Jak pokazano na rysunku, bramka i zacisk źródła obciążenia są połączone; Zatem V GS = 0. Zatem napięcie progowe obciążenia jest ujemne. W związku z tym,

$$V_{GS,load}> V_{T,load}$$ jest spełniony

Dlatego urządzenie obciążające zawsze ma kanał przewodzący, niezależnie od poziomu napięcia wejściowego i wyjściowego.

Gdy tranzystor obciążenia znajduje się w obszarze nasycenia, prąd obciążenia jest określony przez

$$I_{D,load} = \frac{K_{n,load}}{2}\left [ -V_{T,load}\left ( V_{out} \right ) \right ]^{2}$$

Gdy tranzystor obciążenia jest w obszarze liniowym, prąd obciążenia jest określony przez

$$I_{D,load} = \frac{K_{n,load}}{2}\left [ 2\left | V_{T,load}\left ( V_{out} \right ) \right |.\left ( V_{DD}-V_{out} \right )-\left ( V_{DD}-V_{out} \right )^{2} \right ]$$

Charakterystykę przenoszenia napięcia falownika obciążenia zubożonego przedstawiono na poniższym rysunku -

Falownik CMOS - obwód, działanie i opis

Obwód falownika CMOS pokazano na rysunku. Tutaj tranzystory nMOS i pMOS działają jako tranzystory sterownika; gdy jeden tranzystor jest włączony, drugi jest wyłączony.

Ta konfiguracja nazywa się complementary MOS (CMOS). Wejście jest podłączone do zacisku bramki obu tranzystorów tak, że oba mogą być bezpośrednio zasilane napięciem wejściowym. Podłoże nMOS jest podłączone do uziemienia, a podłoże pMOS jest podłączone do źródła zasilania V DD .

Więc V SB = 0 dla obu tranzystorów.

$$V_{GS,n}=V_{in}$$

$$V_{DS,n}=V_{out}$$

I,

$$V_{GS,p}=V_{in}-V_{DD}$$

$$V_{DS,p}=V_{out}-V_{DD}$$

Gdy wejście nMOS jest mniejsze niż napięcie progowe (V w <V TO, n ), nMOS jest odcięte i pMOS jest w obszarze liniowym. Zatem prąd drenu obu tranzystorów wynosi zero.

$$I_{D,n}=I_{D,p}=0$$

Dlatego napięcie wyjściowe V OH jest równe napięciu zasilania.

$$V_{out}=V_{OH}=V_{DD}$$

Gdy napięcie wejściowe jest większe niż V DD + V TO, p , tranzystor pMOS znajduje się w obszarze odcięcia, a nMOS jest w obszarze liniowym, więc prąd drenu obu tranzystorów wynosi zero.

$$I_{D,n}=I_{D,p}=0$$

Dlatego napięcie wyjściowe V OL jest równe zeru.

$$V_{out}=V_{OL}=0$$

NMOS działa w obszarze nasycenia, jeśli V w > V TO i jeśli spełnione są następujące warunki.

$$V_{DS,n}\geq V_{GS,n}-V_{TO,n} $$

$$V_{out}\geq V_{in}-V_{TO,n} $$

PMOS działa w obszarze nasycenia, jeśli V w <V DD + V TO, p i jeśli spełnione są następujące warunki.

$$V_{DS,p}\leq V_{GS,p}-V_{TO,p} $$

$$V_{out}\leq V_{in}-V_{TO,p} $$

Dla różnych wartości napięć wejściowych, obszary pracy są wymienione poniżej dla obu tranzystorów.

Region V w V się nMOS pMOS
ZA <V TO, rz V OH Odciąć Liniowy
b V IL Wysoka ≈ V OH Nasycenie Liniowy
do V th V th Nasycenie Nasycenie
re V IH Niski ≈ V OL Liniowy Nasycenie
mi > (V DD + V TO, p ) V OL Liniowy Odciąć

VTC CMOS pokazano na poniższym rysunku -

Obwody lub bramki logiczne kombinacyjne, które wykonują operacje boolowskie na wielu zmiennych wejściowych i określają wyjścia jako funkcje boolowskie wejść, są podstawowymi elementami składowymi wszystkich systemów cyfrowych. Przeanalizujemy proste konfiguracje obwodów, takie jak dwuwejściowe bramki NAND i NOR, a następnie rozszerzymy naszą analizę o bardziej ogólne przypadki struktur obwodów z wieloma wejściami.

Następnie obwody logiczne CMOS zostaną przedstawione w podobny sposób. Podkreślimy podobieństwa i różnice między logiką zubożenia nMOS a układami logicznymi CMOS i wskażemy na przykładach zalety bramek CMOS. W swojej najbardziej ogólnej postaci kombinacyjny obwód logiczny lub bramka wykonująca funkcję boolowską można przedstawić jako system z wieloma wejściami i jednym wyjściem, jak pokazano na rysunku.

Napięcia węzłów w odniesieniu do potencjału ziemi reprezentują wszystkie zmienne wejściowe. Stosując konwencję logiki dodatniej, wartość boolowska (lub logiczna) „1” może być reprezentowana przez wysokie napięcie VDD, a wartość boolowska (lub logiczna) „0” może być reprezentowana przez niskie napięcie równe 0. Wyjście węzeł jest obciążony pojemnością C L , która reprezentuje połączone pojemności urządzenia pasożytniczego w obwodzie.

Obwody logiczne CMOS

CMOS Podwójna bramka NOR

Obwód składa się z równolegle połączonej n-sieci i połączonej szeregowo, uzupełniającej sieci typu p-net. Napięcia wejściowe V X i V Y są przykładane do bramek jednego tranzystora nMOS i jednego tranzystora pMOS.

Kiedy jedno lub oba wejścia są wysokie, tj. Gdy n-net tworzy ścieżkę przewodzącą między węzłem wyjściowym a ziemią, p-net jest odcinany. Jeżeli oba napięcia wejściowe są niskie, tj. N-net jest odcięty, wówczas p-net tworzy ścieżkę przewodzącą między węzłem wyjściowym a napięciem zasilającym.

Dla dowolnej kombinacji wejść komplementarna struktura obwodu jest taka, że ​​wyjście jest podłączone albo do V DD albo do masy poprzez ścieżkę o niskiej rezystancji, a ścieżka prądu stałego między V DD a masą nie jest ustanowiona dla żadnej kombinacji wejść. Napięcie wyjściowe CMOS, dwie wejściowe bramki NOR otrzymają logicznie niskie napięcie V OL = 0 i logicznie wysokie napięcie V OH = V DD . Równanie progu przełączania napięcia V th jest podane wzorem

$$V_{th}\left ( NOR2 \right ) = \frac{V_{T,n}+\frac{1}{2}\sqrt{\frac{k_{p}}{k_{n}}\left ( V_{DD}-\left | V_{T,p} \right | \right )}}{1+\frac{1}{2}\sqrt{\frac{k_{p}}{k_{n}}}}$$

Układ 2-wejściowej bramki NOR CMOS

Rysunek przedstawia przykładowy układ 2-wejściowej bramki NOR CMOS, wykorzystującej jednowarstwowy metal i jednowarstwowy polikrzem. Cechy tego układu to -

  • Pojedyncze pionowe polilinie dla każdego wejścia
  • Pojedyncze aktywne kształty odpowiednio dla urządzeń N i P.
  • Metalowe autobusy jeżdżące poziomo

Schemat dla bramki CMOS N0R2 pokazano na poniższym rysunku; który odpowiada bezpośrednio układowi, ale nie zawiera informacji W i L. Obszary dyfuzyjne są przedstawione za pomocą prostokątów, metalowe połączenia oraz ciągłe linie i okręgi reprezentują odpowiednio kontakty, a kreskowane paski przedstawiają kolumny polikrzemu. Diagram prętowy jest przydatny do planowania optymalnej topologii układu.

Podwójna bramka NAND CMOS

Schemat obwodu dwóch wejściowych bramek CMOS NAND przedstawiono na poniższym rysunku.

Zasada działania obwodu jest dokładnie podwójna w stosunku do operacji CMOS z dwoma wejściami NOR. Sieć n-net składająca się z dwóch połączonych szeregowo tranzystorów nMOS tworzy ścieżkę przewodzącą między węzłem wyjściowym a uziemieniem, jeśli oba napięcia wejściowe są logicznie wysokie. Oba równolegle połączone tranzystory pMOS w sieci p-net będą wyłączone.

Dla wszystkich innych kombinacji wejść jeden lub oba tranzystory pMOS zostaną włączone, podczas gdy p - net zostanie odcięty, tworząc w ten sposób ścieżkę prądową między węzłem wyjściowym a napięciem zasilania. Próg przełączania dla tej bramki uzyskuje się jako -

$$V_{th}\left ( NAND2 \right ) = \frac{V_{T,n}+2\sqrt{\frac{k_{p}}{k_{n}}\left ( V_{DD}-\left | V_{T,p} \right | \right )}}{1+2\sqrt{\frac{k_{p}}{k_{n}}}}$$

Cechy tego układu są następujące -

  • Pojedyncze linie polikrzemu dla wejść biegną pionowo w obu regionach aktywnych N i P.
  • Pojedyncze aktywne kształty są używane do budowy zarówno urządzeń nMOS, jak i obu urządzeń pMOS.
  • Magistrala zasilania przebiega poziomo w górnej i dolnej części układu.
  • Przewody wyjściowe biegną poziomo, co ułatwia podłączenie do sąsiedniego obwodu.

Złożone obwody logiczne

Złożona brama logiczna obciążenia NMOS

Aby zrealizować złożone funkcje wielu zmiennych wejściowych, podstawowe struktury obwodów i zasady projektowania opracowane dla NOR i NAND można rozszerzyć na złożone bramki logiczne. Możliwość realizacji złożonych funkcji logicznych przy użyciu niewielkiej liczby tranzystorów jest jedną z najbardziej atrakcyjnych cech układów logicznych nMOS i CMOS. Jako przykład rozważmy następującą funkcję logiczną.

$$\overline{Z=P\left ( S+T \right )+QR}$$

Złożona bramka logiczna nMOS zubażania-obciążenia używana do realizacji tej funkcji jest pokazana na rysunku. Na tym rysunku lewa gałąź sterownika nMOS, składająca się z trzech tranzystorów sterownika, jest wykorzystywana do realizacji funkcji logicznej P (S + T), podczas gdy gałąź po prawej stronie pełni funkcję QR. Łącząc równolegle dwie gałęzie i umieszczając tranzystor obciążający między węzłem wyjściowym a napięciem zasilaniaVDD,otrzymujemy daną funkcję złożoną. Każda zmienna wejściowa jest przypisana tylko do jednego sterownika.

Inspekcja topologii obwodu daje proste zasady projektowania sieci rozwijanej -

  • Operacje OR są wykonywane przez sterowniki połączone równolegle.
  • Operacje AND są wykonywane przez sterowniki połączone szeregowo.
  • Odwrócenie jest zapewnione przez naturę działania obwodu MOS.

Jeśli wszystkie zmienne wejściowe mają wysoki stan logiczny w obwodzie realizującym funkcję, odpowiedni sterownik (W/L) stosunek sieci pull-down składającej się z pięciu tranzystorów nMOS wynosi

$$\frac{W}{L}=\frac{1}{\frac{1}{\left ( W/L \right )Q}+\frac{1}{\left ( W/L \right )R}}+\frac{1}{\frac{1}{\left ( W/L \right )P}+\frac{1}{\left ( W/L \right )S+\left ( W/L \right )Q}}$$

Złożone bramki logiczne CMOS

Realizacja sieci n-net lub sieci typu pull-down opiera się na tych samych podstawowych zasadach projektowych, które zostały zbadane dla złożonej bramki logicznej nMOS ze zubożeniem obciążenia. Sieć podciągająca pMOS musi być podwójną siecią n-net.

Oznacza to, że wszystkie połączenia równoległe w sieci nMOS będą odpowiadać połączeniom szeregowym w sieci pMOS, a wszystkie połączenia szeregowe w sieci nMOS odpowiadają połączeniom równoległym w sieci pMOS. Rysunek przedstawia prostą konstrukcję wykresu dual p-net (pull-up) z wykresu n-net (pull-down).

Każdy tranzystor sterownika w sieci rozwijanej jest pokazany jako ai, a każdy węzeł jest pokazany jako wierzchołek na wykresie rozwijanym. Następnie w każdym ograniczonym obszarze na wykresie ściągania tworzony jest nowy wierzchołek, a sąsiednie wierzchołki są połączone krawędziami, które przecinają każdą krawędź na wykresie rozwijanym tylko raz. Ten nowy wykres przedstawia sieć podciągającą.

Technika układu przy użyciu metody wykresu Eulera

Rysunek przedstawia implementację złożonej funkcji CMOS i jej diagram w postaci styków z dowolną kolejnością bramek, co daje bardzo nieoptymalny układ dla bramki CMOS.

W takim przypadku separacja między kolumnami polikrzemu musi umożliwiać separację dyfuzyjno-dyfuzyjną pomiędzy nimi. To z pewnością pochłania znaczną ilość dodatkowej powierzchni krzemu.

Korzystając ze ścieżki Eulera, możemy uzyskać optymalny układ. Ścieżka Eulera jest definiowana jako nieprzerwana ścieżka, która przechodzi przez każdą krawędź (gałąź) wykresu dokładnie raz. Znajdź ścieżkę Eulera zarówno na rozwijanym wykresie drzewa, jak i na rozwijanym wykresie drzewa z identyczną kolejnością wejść.

Obwody logiczne są podzielone na dwie kategorie - (a) Obwody kombinacyjne i (b) Obwody sekwencyjne.

W obwodach kombinacyjnych wyjście zależy tylko od stanu najnowszych wejść.

W układach sekwencyjnych wyjście zależy nie tylko od najnowszych wejść, ale także od stanu wcześniejszych wejść. Układy sekwencyjne zawierają elementy pamięci.

Obwody sekwencyjne są trzech typów -

Bistable- Obwody bistabilne mają dwa stabilne punkty pracy i będą w każdym ze stanów. Przykład - komórki pamięci, zatrzaski, przerzutniki i rejestry.

Monostable- Obwody monostabilne mają tylko jeden stabilny punkt pracy i nawet jeśli są chwilowo zakłócone do stanu przeciwnego, z czasem powrócą do swojego stabilnego punktu pracy. Przykład: timery, generatory impulsów.

Astable- obwody nie mają stabilnego punktu pracy i oscylują między kilkoma stanami. Przykład - oscylator pierścieniowy.

Obwody logiczne CMOS

SR Latch oparty na bramie NOR

Jeśli ustawione wejście (S) jest równe logice "1" a wejście resetowania jest równe logice "0." wtedy wyjście Q będzie zmuszone do logiki "1". Podczas$\overline{Q}$ jest zmuszony do logiki "0". Oznacza to, że zatrzask SR zostanie ustawiony niezależnie od poprzedniego stanu.

Podobnie, jeśli S jest równe „0” i R jest równe "1" wtedy wyjście Q zostanie zmuszone do "0" podczas $\overline{Q}$ jest do tego zmuszony "1". Oznacza to, że zatrzask jest resetowany, niezależnie od wcześniejszego stanu wstrzymania. Wreszcie, jeśli oba wejścia S i R są równe logice"1" wtedy oba wyjścia będą zmuszone do logiki "0" co jest sprzeczne z komplementarnością Q i $\overline{Q}$.

Dlatego ta kombinacja wejść jest niedozwolona podczas normalnej pracy. Tabela prawdy SR Latch na bazie NOR jest podana w tabeli.

S R Q $\overline{Q}$ Operacja
0 0 Q $\overline{Q}$ Trzymać
1 0 1 0 Zestaw
0 1 0 1 Resetowanie
1 1 0 0 Nie dozwolony

Na poniższym rysunku pokazano zatrzask CMOS SR oparty na bramce NOR.

Jeśli S jest równe V OH, a R jest równe V OL , oba równolegle połączone tranzystory M1 i M2 będą włączone. Napięcie na węźle$\overline{Q}$przyjmie niski poziom logiczny V OL = 0.

W tym samym czasie zarówno M3, jak i M4 są wyłączone, co skutkuje wysokim napięciem logicznym V OH w węźle Q. Jeśli R jest równe V OH, a S jest równe V OL , M1 i M2 są wyłączone i Włączone M3 i M4.

Zatrzask SR oparty na bramce NAND

Schemat blokowy i schemat poziomu bramki zatrzasku SR opartego na NAND pokazano na rysunku. Małe kółka na zaciskach wejściowych S i R oznaczają, że obwód reaguje na aktywne niskie sygnały wejściowe. Tabela prawdy zatrzasku SR opartego na NAND jest podana w tabeli

S R Q Q ′
0 0 NC NC Bez zmiany. Zatrzask pozostał w obecnym stanie.
1 0 1 0 Zestaw zatrzasków.
0 1 0 1 RESET zatrzasku.
1 1 0 0 Nieprawidłowy stan.

Jeśli S idzie do 0 (podczas gdy R = 1), Q idzie wysoko, ciągnąc $\overline{Q}$ niski i zatrzask przechodzi w stan Set

S = 0 wtedy Q = 1 (jeśli R = 1)

Jeśli R osiągnie 0 (podczas gdy S = 1), Q idzie wysoko, ciągnąc $\overline{Q}$ niski i zatrzask jest resetowany

R = 0 wtedy Q = 1 (jeśli S = 1)

Stan wstrzymania wymaga, aby zarówno S, jak i R były wysokie. Jeśli S = R = 0, wyjście nie jest dozwolone, ponieważ spowodowałoby to stan nieokreślony. Zatrzask CMOS SR oparty na bramce NAND pokazano na rysunku.

Obciążenie wyczerpujące nMOS SR Zatrzask oparty na bramce NAND pokazano na rysunku. Działanie jest podobne do działania zatrzasku CMOS NAND SR. Implementacja obwodu CMOS ma niskie rozpraszanie mocy statycznej i wysoki margines szumów.

Obwody logiczne CMOS

Taktowany zatrzask SR

Rysunek przedstawia zatrzask SR oparty na NOR z dodanym zegarem. Zatrzask reaguje na wejścia S i R tylko wtedy, gdy CLK jest wysoki.

Gdy CLK jest niski, zatrzask zachowuje swój aktualny stan. Zauważ, że Q zmienia stan -

  • Kiedy S rośnie podczas dodatniego CLK.
  • Na wiodącym zboczu CLK po zmianach S i R podczas niskiego czasu CLK.
  • Pozytywny błąd w S, podczas gdy CLK jest wysokie
  • Kiedy R rośnie podczas dodatniego CLK.

Implementacja CMOS AOI taktowanego zatrzasku SR opartego na NOR jest pokazana na rysunku. Zauważ, że potrzeba tylko 12 tranzystorów.

  • Gdy CLK jest niski, dwa zaciski szeregowe w drzewie N są otwarte, a dwa równoległe tranzystory w drzewie P są włączone, zachowując w ten sposób stan w komórce pamięci.

  • Gdy zegar jest wysoki, obwód staje się po prostu zatrzaskiem CMOS opartym na NOR, który zareaguje na wejście S i R.

Clocked SR Latch based on NAND Gate

Obwód jest realizowany z czterema bramkami NAND. Jeśli ten obwód jest zaimplementowany z CMOS, to wymaga 16 tranzystorów.

  • Zatrzask reaguje na S lub R tylko wtedy, gdy CLK jest wysoki.
  • Jeśli oba sygnały wejściowe i sygnały CLK są aktywne w stanie wysokim: tj. Wyjście zatrzaskowe Q zostanie ustawione, gdy CLK = „1” S = „1” i R = „0”
  • Podobnie, zatrzask zostanie zresetowany, gdy CLK = "1," S = "0" i

Gdy CLK jest niski, zatrzask zachowuje swój obecny stan.

Taktowany zatrzask JK

Powyższy rysunek przedstawia taktowany zatrzask JK oparty na bramkach NAND. Wadą zatrzasku SR jest to, że gdy oba S i R są wysokie, jego stan wyjściowy staje się nieokreślony. Zatrzask JK eliminuje ten problem, wykorzystując sprzężenie zwrotne od wyjścia do wejścia, tak że wszystkie stany wejściowe tabeli prawdy są dopuszczalne. Jeśli J = K = 0, zatrzask utrzyma swój obecny stan.

Jeśli J = 1 i K = 0, zatrzask ustawi się na kolejnym dodatnim zboczu zegara, tj. Q = 1, $\overline{Q}$ = 0

Jeśli J = 0 i K = 1, zatrzask zresetuje się przy następnym dodatnim zboczu zegara, tj. Q = 1 i $\overline{Q}$ = 0.

Jeśli J = K = 1, zatrzask przełączy się na następnej dodatniej krawędzi zegara

Działanie taktowanego zatrzasku JK podsumowano w tabeli prawdy podanej w tabeli.

J

K

Q

$\overline{Q}$

S

R

Q

$\overline{Q}$

Operation

0 0 0 1 1 1 0 1 Trzymać
1 0 1 1 1 0
0 1 0 1 1 1 0 1 Resetowanie
1 0 1 0 0 1
1 0 0 1 0 1 1 0 Zestaw
1 0 1 1 1 0
1 1 0 1 0 1 1 0 przełącznik
1 0 1 0 0 1

Implementacja zatrzasku CMOS D.

Zatrzask D jest zwykle realizowany z przełącznikami bramki transmisyjnej (TG), jak pokazano na rysunku. Wejście TG jest aktywowane za pomocą CLK, podczas gdy pętla sprzężenia zwrotnego zatrzasku TG jest aktywowana przez CLK. Wejście D jest akceptowane, gdy CLK jest wysoki. Kiedy CLK idzie w stan niski, wejście jest rozwarte, a zatrzask jest ustawiony z wcześniejszymi danymi D.

VHDL oznacza język opisu sprzętu z układami scalonymi o bardzo dużej szybkości. Jest to język programowania używany do modelowania systemu cyfrowego za pomocą przepływu danych, behawioralnego i strukturalnego stylu modelowania. Język ten został po raz pierwszy wprowadzony w 1981 roku dla Departamentu Obrony (DoD) w ramach programu VHSIC.

Opisywanie projektu

W języku VHDL encja jest używana do opisu modułu sprzętowego. Podmiot można opisać za pomocą,

  • Deklaracja podmiotu
  • Architecture
  • Configuration
  • Deklaracja paczki
  • Treść pakietu

Zobaczmy, co to jest?

Deklaracja podmiotu

Definiuje nazwy, sygnały wejściowe i wyjściowe oraz tryby modułu sprzętowego.

Syntax -

entity entity_name is
   Port declaration;
end entity_name;

Deklaracja encji powinna zaczynać się od słowa „entity” i kończyć słowami kluczowymi „end”. Kierunkiem będzie wejście, wyjście lub wejście.

W Port można odczytać
Na zewnątrz Port można zapisać
Inout Port można odczytywać i zapisywać
Bufor Port można odczytywać i zapisywać, może mieć tylko jedno źródło.

Architecture -

Architekturę można opisać za pomocą stylu strukturalnego, przepływu danych, behawioralnego lub mieszanego.

Syntax -

architecture architecture_name of entity_name 
architecture_declarative_part;

begin
   Statements;
end architecture_name;

Tutaj powinniśmy określić nazwę jednostki, dla której piszemy treść architektury. Instrukcje dotyczące architektury powinny znajdować się wewnątrz słów kluczowych „begin” i „énd”. Część deklaratywna architektury może zawierać zmienne, stałe lub deklaracje komponentów.

Modelowanie przepływu danych

W tym stylu modelowania przepływ danych przez jednostkę jest wyrażany za pomocą sygnału współbieżnego (równoległego). Równoczesne instrukcje w języku VHDL to WHEN i GENERATE.

Oprócz nich do konstruowania kodu można również użyć przypisań wykorzystujących tylko operatory (AND, NOT, +, *, sll itp.).

Wreszcie, w tego rodzaju kodzie można również zastosować specjalny rodzaj przypisania, zwany BLOKIEM.

W kodzie współbieżnym można użyć:

  • Operators
  • Instrukcja WHEN (WHEN / ELSE lub WITH / SELECT / WHEN);
  • Instrukcja GENERATE;
  • Instrukcja BLOCK

Modelowanie behawioralne

W tym stylu modelowania zachowanie jednostki jako zestawu instrukcji jest wykonywane sekwencyjnie w określonej kolejności. Tylko instrukcje umieszczone wewnątrz PROCESU, FUNKCJI lub PROCEDURY są sekwencyjne.

PROCESY, FUNKCJE i PROCEDURY to jedyne sekcje kodu, które są wykonywane sekwencyjnie.

Jednak jako całość każdy z tych bloków jest nadal współbieżny z innymi instrukcjami umieszczonymi poza nim.

Jednym z ważnych aspektów kodu zachowań jest to, że nie jest on ograniczony do logiki sekwencyjnej. Rzeczywiście, dzięki niemu możemy budować układy sekwencyjne, a także układy kombinacyjne.

Instrukcje zachowania to IF, WAIT, CASE i LOOP. ZMIENNE są również ograniczone i powinny być używane tylko w kodzie sekwencyjnym. VARIABLE nigdy nie może być globalna, więc jej wartość nie może być przekazywana bezpośrednio.

Modelowanie strukturalne

W tym modelowaniu jednostka jest opisywana jako zbiór połączonych ze sobą komponentów. Instrukcja tworzenia instancji składnika jest instrukcją współbieżną. Dlatego kolejność tych stwierdzeń nie jest ważna. Strukturalny styl modelowania opisuje jedynie wzajemne połączenia komponentów (postrzegane jako czarne skrzynki), bez narzucania jakiegokolwiek zachowania samych komponentów ani bytu, który wspólnie reprezentują.

W modelowaniu strukturalnym ciało architektury składa się z dwóch części - części deklaratywnej (przed słowem kluczowym begin) i części instrukcji (po słowie kluczowym begin).

Operacja logiczna - AND GATE

X Y Z
0 0 0
0 1 0
1 0 0
1 1 1

VHDL Code:
Library ieee;
use ieee.std_logic_1164.all;

entity and1 is
   port(x,y:in bit ; z:out bit);
end and1;

architecture virat of and1 is
begin
   z<=x and y; 
end virat;

Przebiegi

Operacja logiczna - OR Brama

X Y Z
0 0 0
0 1 1
1 0 1
1 1 1

VHDL Code: 
Library ieee; 
use ieee.std_logic_1164.all;  

entity or1 is
   port(x,y:in bit ; z:out bit); 
end or1; 
 
architecture virat of or1 is
begin
   z<=x or y; 
end virat;

Przebiegi

Operacja logiczna - NIE bramka

X Y
0 1
1 0

VHDL Code:
  
Library ieee; 
use ieee.std_logic_1164.all; 
 
entity not1 is
   port(x:in bit ; y:out bit); 
end not1; 
 
architecture virat of not1 is
begin
   y<=not x;
end virat;

Przebiegi

Operacja logiczna - bramka NAND

X Y z
0 0 1
0 1 1
1 0 1
1 1 0

VHDL Code:
  
Library ieee; 
use ieee.std_logic_1164.all; 

entity nand1 is
   port(a,b:in bit ; c:out bit); 
end nand1; 
 
architecture virat of nand1 is
begin
   c<=a nand b; 
end virat;

Przebiegi

Operacja logiczna - bramka NOR

X Y z
0 0 1
0 1 0
1 0 0
1 1 0

VHDL Code: 
 
Library ieee; 
use ieee.std_logic_1164.all; 
 
entity nor1 is
   port(a,b:in bit ; c:out bit); 
end nor1; 
 
architecture virat of nor1 is
begin
   c<=a nor b;
end virat;

Przebiegi

Operacja logiczna - bramka XOR

X Y Z
0 0 1
0 1 1
1 0 1
1 1 0

VHDL Code: 
 
Library ieee; 
use ieee.std_logic_1164.all;
  
entity xor1 is
   port(a,b:in bit ; c:out bit); 
end xor1;
  
architecture virat of xor1 is
begin
   c<=a xor b; 
end virat;

Przebiegi

Operacja logiczna - bramka X-NOR

X Y Z
0 0 1
0 1 1
1 0 1
1 1 0

VHDL Code: 
 
Library ieee; 
use ieee.std_logic_1164.all; 

entity xnor1 is
   port(a,b:in bit ; c:out bit); 
end xnor1; 
 
architecture virat of xnor1 is
begin
   c<=not(a xor b); 
end virat;

Przebiegi

W tym rozdziale wyjaśniono programowanie w języku VHDL dla obwodów kombinacyjnych.

Kod VHDL dla Half-Addera

VHDL Code:
  
Library ieee; 
use ieee.std_logic_1164.all;
  
entity half_adder is
   port(a,b:in bit; sum,carry:out bit); 
end half_adder; 
 
architecture data of half_adder is
begin
   sum<= a xor b;  
   carry <= a and b;  
end data;

Przebiegi

Kod VHDL dla pełnego dodatku

Library ieee; 
use ieee.std_logic_1164.all;
 
entity full_adder is port(a,b,c:in bit; sum,carry:out bit); 
end full_adder;
  
architecture data of full_adder is
begin
   sum<= a xor b xor c; 
   carry <= ((a and b) or (b and c) or (a and c)); 
end data;

Przebiegi

Kod VHDL dla pół-odejmowania

Library ieee;
use ieee.std_logic_1164.all;
  
entity half_sub is
   port(a,c:in bit; d,b:out bit);
end half_sub;  

architecture data of half_sub is
begin
   d<= a xor c;
   b<= (a and (not c));
end data;

Przebiegi

Kod VHDL dla pełnego odejmowania

Library ieee; 
use ieee.std_logic_1164.all;
  
entity full_sub is
   port(a,b,c:in bit; sub,borrow:out bit); 
end full_sub; 
 
architecture data of full_sub is
begin
   sub<= a xor b xor c; 
   borrow <= ((b xor c) and (not a)) or (b and c); 
end data;

Przebiegi

Kod VHDL dla multipleksera

Library ieee; 
use ieee.std_logic_1164.all;
  
entity mux is
   port(S1,S0,D0,D1,D2,D3:in bit; Y:out bit);
end mux;
  
architecture data of mux is
begin 
   Y<= (not S0 and not S1 and D0) or 
      (S0 and not S1 and D1) or 
      (not S0 and S1 and D2) or
      (S0 and S1 and D3); 
end data;

Przebiegi

Kod VHDL dla demultipleksera

Library ieee; 
use ieee.std_logic_1164.all;
  
entity demux is
   port(S1,S0,D:in bit; Y0,Y1,Y2,Y3:out bit); 
end demux;
  
architecture data of demux is
begin 
   Y0<=  ((Not S0) and (Not S1) and D); 
   Y1<=  ((Not S0) and S1 and D); 
   Y2<=  (S0 and (Not S1) and D); 
   Y3<=  (S0 and S1 and D); 
end data;

Przebiegi

Kod VHDL dla enkodera 8 x 3

library ieee; 
use ieee.std_logic_1164.all; 
 
entity enc is
   port(i0,i1,i2,i3,i4,i5,i6,i7:in bit; o0,o1,o2: out bit); 
end enc; 
 
architecture vcgandhi of enc is
begin 
   o0<=i4 or i5 or i6 or i7; 
   o1<=i2 or i3 or i6 or i7; 
   o2<=i1 or i3 or i5 or i7; 
end vcgandhi;

Przebiegi

Kod VHDL dla dekodera 3 x 8

library ieee; 
use ieee.std_logic_1164.all;

entity dec is
   port(i0,i1,i2:in bit; o0,o1,o2,o3,o4,o5,o6,o7: out bit); 
end dec; 
 
architecture vcgandhi of dec is
begin 
   o0<=(not i0) and (not i1) and (not i2); 
   o1<=(not i0) and (not i1) and i2; 
   o2<=(not i0) and i1 and (not i2); 
   o3<=(not i0) and i1 and i2; 
   o4<=i0 and (not i1) and (not i2); 
   o5<=i0 and (not i1) and i2; 
   o6<=i0 and i1 and (not i2); 
   o7<=i0 and i1 and i2; 
end vcgandhi;

Przebiegi

Kod VHDL - 4-bitowy dodatek równoległy

library IEEE; 
use IEEE.STD_LOGIC_1164.all;
  
entity pa is
   port(a : in STD_LOGIC_VECTOR(3 downto 0);
      b : in STD_LOGIC_VECTOR(3 downto 0);
      ca : out STD_LOGIC;
      sum : out STD_LOGIC_VECTOR(3 downto 0) 
   ); 
end pa; 
 
architecture vcgandhi of pa is
   Component fa is
      port (a : in STD_LOGIC; 
         b : in STD_LOGIC; 
         c : in STD_LOGIC; 
         sum : out STD_LOGIC; 
         ca : out STD_LOGIC
      ); 
   end component;         
   signal s : std_logic_vector (2 downto 0); 
   signal temp: std_logic;
begin 
   temp<='0'; 
   u0 : fa port map (a(0),b(0),temp,sum(0),s(0)); 
   u1 : fa port map (a(1),b(1),s(0),sum(1),s(1)); 
   u2 : fa port map (a(2),b(2),s(1),sum(2),s(2));
   ue : fa port map (a(3),b(3),s(2),sum(3),ca);  
end vcgandhi;

Przebiegi

Kod VHDL - 4-bitowy kontroler parzystości

library ieee; 
use ieee.std_logic_1164.all; 
 
entity parity_checker is 
   port (a0,a1,a2,a3 : in std_logic; 
      p : out std_logic); 
end parity_checker;  

architecture vcgandhi of parity_checker is 
begin    
   p <= (((a0 xor a1) xor a2) xor a3); 
end vcgandhi;

Przebiegi

Kod VHDL - 4-bitowy generator parzystości

library ieee;
use ieee.std_logic_1164.all;

entity paritygen is
   port (a0, a1, a2, a3: in std_logic; p_odd, p_even: out std_logic);
end paritygen;  

architecture vcgandhi of paritygen is
begin
   process (a0, a1, a2, a3)
   
	if (a0 ='0' and a1 ='0' and a2 ='0' and a3 =’0’)
      then odd_out <= "0";
      even_out <= "0";
   else
      p_odd <= (((a0 xor a1) xor a2) xor a3);
      p_even <= not(((a0 xor a1) xor a2) xor a3);  
end vcgandhi

Przebiegi

W tym rozdziale wyjaśniono, jak wykonać programowanie w języku VHDL dla obwodów sekwencyjnych.

Kod VHDL dla zatrzasku SR

library ieee; 
use ieee.std_logic_1164.all;
  
entity srl is 
   port(r,s:in bit; q,qbar:buffer bit); 
end srl;  

architecture virat of srl is 
   signal s1,r1:bit; 
begin 
   q<= s nand qbar; 
   qbar<= r nand q; 
end virat;

Przebiegi

Kod VHDL dla zatrzasku D.

library ieee; 
use ieee.std_logic_1164.all;

entity Dl is 
   port(d:in bit; q,qbar:buffer bit); 
end Dl; 
 
architecture virat of Dl is 
   signal s1,r1:bit; 
begin 
   q<= d nand qbar; 
   qbar<= d nand q; 
end virat;

Przebiegi

Kod VHDL dla Flip Flop SR

library ieee; 
use ieee.std_logic_1164.all;
  
entity srflip is 
   port(r,s,clk:in bit; q,qbar:buffer bit); 
end srflip;
  
architecture virat of srflip is 
   signal s1,r1:bit; 
begin 
   s1<=s nand clk; 
   r1<=r nand clk;
   q<= s1 nand qbar;
   qbar<= r1 nand q;
end virat;

Przebiegi

Kod VHDL dla JK Flip Flop

library IEEE; 
use IEEE.STD_LOGIC_1164.all;  

entity jk is 
   port(
      j : in STD_LOGIC; 
      k : in STD_LOGIC; 
      clk : in STD_LOGIC; 
      reset : in STD_LOGIC; 
      q : out STD_LOGIC; 
      qb : out STD_LOGIC 
   ); 
end jk;
  
architecture virat of jk is 
begin 
   jkff : process (j,k,clk,reset) is 
   variable m : std_logic := '0'; 
   
   begin 
      if (reset = '1') then 
         m : = '0'; 
      elsif (rising_edge (clk)) then 
         if (j/ = k) then
            m : = j; 
         elsif (j = '1' and k = '1') then 
            m : = not m; 
         end if; 
      end if; 
      
      q <= m; 
      qb <= not m; 
   end process jkff; 
end virat;

Przebiegi

Kod VHDL dla przerzutnika typu D.

Library ieee; 
use ieee.std_logic_1164.all;  

entity dflip is 
   port(d,clk:in bit; q,qbar:buffer bit); 
end dflip; 
 
architecture virat of dflip is 
   signal d1,d2:bit; 
begin 
   d1<=d nand clk; 
   d2<=(not d) nand clk; 
   q<= d1 nand qbar; 
   qbar<= d2 nand q; 
end virat;

Przebiegi

Kod VHDL dla T Flip Flop

library IEEE; 
use IEEE.STD_LOGIC_1164.all;  

entity Toggle_flip_flop is 
   port( 
      t : in STD_LOGIC; 
      clk : in STD_LOGIC; 
      reset : in STD_LOGIC; 
      dout : out STD_LOGIC
   ); 
end Toggle_flip_flop;  

architecture virat of Toggle_flip_flop is 
begin 
   tff : process (t,clk,reset) is 
   variable m : std_logic : = '0'; 
   
   begin 
      if (reset = '1') then 
         m : = '0'; 
      elsif (rising_edge (clk)) then 
         if (t = '1') then 
            m : = not m;        
         end if; 
      end if; 
      dout < = m; 
   end process tff; 
end virat;

Przebiegi

Kod VHDL dla 4-bitowego licznika w górę

library IEEE; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all;
  
entity counter is 
   port(Clock, CLR : in std_logic; 
      Q : out std_logic_vector(3 downto 0)
   ); 
end counter;  

architecture virat of counter is 
   signal tmp: std_logic_vector(3 downto 0); 
begin 
   process (Clock, CLR) 
   
   begin 
      if (CLR = '1') then 
         tmp < = "0000"; 
      elsif (Clock'event and Clock = '1') then 
         mp <= tmp + 1; 
      end if; 
   end process; 
   Q <= tmp; 
end virat;

Przebiegi

Kod VHDL dla 4-bitowego licznika w dół

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all;
  
entity dcounter is 
   port(Clock, CLR : in std_logic; 
      Q : out std_logic_vector(3 downto 0)); 
end dcounter; 
 
architecture virat of dcounter is 
   signal tmp: std_logic_vector(3 downto 0); 

begin 
   process (Clock, CLR) 
   begin 
      if (CLR = '1') then 
         tmp <= "1111"; 
      elsif (Clock'event and Clock = '1') then 
         tmp <= tmp - 1; 
      end if; 
   end process; 
   Q <= tmp; 
end virat;

Przebiegi

Verilog to JĘZYK OPISU SPRZĘTU (HDL). Jest to język używany do opisu systemu cyfrowego, takiego jak przełącznik sieciowy, mikroprocesor, pamięć lub przerzutnik. Oznacza to, że używając HDL możemy opisać dowolny sprzęt cyfrowy na dowolnym poziomie. Projekty, które są opisane w HDL są niezależne od technologii, bardzo łatwe do projektowania i debugowania i są zwykle bardziej przydatne niż schematy, szczególnie w przypadku dużych obwodów.

Verilog obsługuje projekty na wielu poziomach abstrakcji. Trzy główne to -

  • Poziom behawioralny
  • Poziom przeniesienia rejestru
  • Poziom bramy

Poziom behawioralny

Ten poziom opisuje system za pomocą współbieżnych algorytmów (behawioralnych). Każdy algorytm jest sekwencyjny, co oznacza, że ​​składa się z zestawu instrukcji, które są wykonywane jedna po drugiej. Funkcje, zadania i bloki to główne elementy. Nie ma znaczenia konstrukcyjna realizacja projektu.

Rejestracja - poziom transferu

Projekty wykorzystujące Register-Transfer Level określają charakterystykę obwodu wykorzystując operacje i przesyłanie danych między rejestrami. Współczesna definicja kodu RTL brzmi: „Każdy kod, który można syntetyzować, nazywa się kodem RTL”.

Poziom bramy

Na poziomie logicznym cechy systemu są opisywane przez łącza logiczne i ich właściwości czasowe. Wszystkie sygnały są sygnałami dyskretnymi. Mogą mieć tylko określone wartości logiczne („0”, „1”, „X”, „Z”). Użyteczne operacje to predefiniowane prymitywy logiczne (podstawowe bramki). Modelowanie na poziomie bramki może nie być dobrym pomysłem do projektowania logiki. Kod poziomu bramki jest generowany przy użyciu narzędzi takich jak narzędzia do syntezy, a jego lista sieci jest używana do symulacji poziomu bramy i do zaplecza.

Tokeny leksykalne

Źródłowe pliki tekstowe języka Verilog to strumień tokenów leksykalnych. Żeton składa się z jednego lub więcej znaków, a każdy pojedynczy znak znajduje się dokładnie w jednym żetonie.

Podstawowe tokeny leksykalne używane przez Verilog HDL są podobne do tych w języku programowania C. Verilog rozróżnia wielkość liter. Wszystkie słowa kluczowe są zapisane małymi literami.

Biała przestrzeń

Spacje mogą zawierać znaki spacji, tabulatorów, nowych wierszy i kanałów informacyjnych. Te postacie są ignorowane, z wyjątkiem sytuacji, gdy służą do oddzielnych żetonów.

Białe znaki to spacja, tabulatory, powrót karetki, nowy wiersz i wysuwy stron.

Komentarze

Istnieją dwa formularze do przedstawiania komentarzy

  • 1) Komentarze jednowierszowe zaczynają się od tokena // i kończą znakiem powrotu karetki.

Np .: // to jest składnia jednowierszowa

  • 2) Komentarze wielowierszowe zaczynają się od tokena / * i kończą tokenem * /

Np .: / * to jest składnia wielowierszowa * /

Liczby

Możesz podać liczbę w formacie binarnym, ósemkowym, dziesiętnym lub szesnastkowym. Liczby ujemne są reprezentowane przez liczby komplementów 2. Verilog dopuszcza liczby całkowite, liczby rzeczywiste oraz liczby ze znakiem i bez znaku.

Składnia jest określona przez - <rozmiar> <radix> <wartość>

Rozmiar lub liczbę bez rozmiaru można zdefiniować w <Rozmiar>, a <radix> określa, czy jest to liczba dwójkowa, ósemkowa, szesnastkowa czy dziesiętna.

Identyfikatory

Identyfikator to nazwa używana do zdefiniowania obiektu, takiego jak funkcja, moduł lub rejestr. Identyfikatory powinny zaczynać się od znaków alfabetycznych lub znaków podkreślenia. Dawny. A_Z, a_z, _

Identyfikatory to kombinacja znaków alfabetycznych, numerycznych, podkreślenia i $. Mogą mieć długość do 1024 znaków.

Operatorzy

Operatory są znakami specjalnymi używanymi do stawiania warunków lub do obsługi zmiennych. Jest jeden, dwa, a czasem trzy znaki używane do wykonywania operacji na zmiennych.

Dawny. >, +, ~, &! =.

Słowa kluczowe Verilog

Słowa, które mają specjalne znaczenie w Verilog, nazywane są słowami kluczowymi Verilog. Na przykład: assign, case, while, wire, reg, and, or, nand i module. Nie powinny być używane jako identyfikatory. Słowa kluczowe Verilog obejmują również dyrektywy kompilatora oraz zadania i funkcje systemowe.

Modelowanie poziomu bramy

Verilog ma wbudowane prymitywy, takie jak bramki logiczne, bramki transmisyjne i przełączniki. Są one rzadko używane w pracach projektowych, ale są używane w świecie postsyntezowym do modelowania komórek ASIC / FPGA.

Modelowanie na poziomie bramy wykazuje dwie właściwości -

Drive strength- Siła bramek wyjściowych jest określana przez siłę napędu. Wyjście jest najsilniejsze, jeśli istnieje bezpośrednie połączenie ze źródłem. Siła maleje, jeśli połączenie jest realizowane przez tranzystor przewodzący, a przynajmniej, gdy jest podłączone przez rezystor podwyższający / obniżający. Siła dysku zwykle nie jest określana, w którym to przypadku wartości domyślne to strong1 i strong0.

Delays- Jeśli opóźnienia nie są określone, bramki nie mają opóźnień propagacji; jeśli określono dwa opóźnienia, to pierwsza reprezentuje opóźnienie narastania, a druga - opadania; jeśli określono tylko jedno opóźnienie, to zarówno wzrost, jak i spadek są równe. Opóźnienia można zignorować w syntezie.

Brama prymitywów

Podstawowe bramki logiczne wykorzystujące jedno wyjście i wiele wejść są używane w Verilog. GATE używa jednego ze słów kluczowych - and, nand, or, nor, xor, xnor do użycia w Verilog dla N liczby wejść i 1 wyjścia.

Example:  
   Module gate() 
   Wire ot0; 
   Wire ot1; 
   Wire ot2; 
   
   Reg in0,in1,in2,in3; 
   Not U1(ot0,in0); 
   Xor U2(ot1,in1,in2,in3); 
   And U3(ot2, in2,in3,in0)

Prymitywy bramy transmisyjnej

Prymitywy bramek transmisji obejmują zarówno bufory, jak i inwertery. Mają jedno wejście i jedno lub więcej wyjść. W przedstawionej poniżej składni tworzenia instancji bramki GATE oznacza słowo kluczowe buf lub NOT gate.

Przykład: Not, buf, bufif0, bufif1, notif0, notif1

Nie - nie ma falownika

Buf - n bufor wyjściowy

Bufifo - bufor trójstanowy, aktywny stan niski

Bufif1 - bufor trójstanowy, aktywny stan wysoki

Notifo - falownik trójstanowy, aktywne niskie zezwolenie

Notif1 - falownik trójstanowy, aktywny stan wysoki

Example:  
   Module gate() 
   Wire out0; 
   Wire out1; 
   
   Reg in0,in1;
   Not U1(out0,in0); 
   Buf U2(out0,in0);

Typy danych

Zestaw wartości

Verilog składa się głównie z czterech podstawowych wartości. Wszystkie typy danych Verilog, które są używane w Verilog, przechowują te wartości -

0 (logiczne zero lub fałszywy warunek)

1 (logiczny jeden lub prawdziwy warunek)

x (nieznana wartość logiczna)

z (stan wysokiej impedancji)

użycie x i z jest bardzo ograniczone do syntezy.

Drut

Drut służy do reprezentowania fizycznego przewodu w obwodzie i służy do łączenia bramek lub modułów. Wartość przewodu można tylko odczytać i nie można jej przypisać w funkcji lub bloku. Przewód nie może przechowywać wartości, ale zawsze jest sterowany przez ciągłą instrukcję przypisania lub przez podłączenie przewodu do wyjścia bramki / modułu. Inne specyficzne typy przewodów to -

Wand (wired-AND) - tutaj wartość Wand zależy od logicznego AND wszystkich sterowników urządzeń do niego podłączonych.

Wor (wired-OR) - tutaj wartość Wor zależy od logicznego LUB wszystkich sterowników urządzeń do niego podłączonych.

Tri (three-state) - tutaj wszystkie sterowniki podłączone do tri muszą być z, z wyjątkiem tylko jednego (który określa wartość tri).

Example: 
   Wire [msb:lsb] wire_variable_list; 
   Wirec // simple wire 
   Wand d; 
   
   Assign d = a; // value of d is the logical AND of 
   Assign d = b; // a and b 
   Wire [9:0] A; // a cable (vector) of 10 wires. 
   
   Wand [msb:lsb] wand_variable_list; 
   Wor [msb:lsb] wor_variable_list; 
   Tri [msb:lsb] tri_variable_list;

Zarejestrować

Reg (rejestr) to obiekt danych, który przechowuje wartość z jednego przypisania proceduralnego do następnego i jest używany tylko w różnych funkcjach i blokach proceduralnych. Reg jest prostym rejestrem Verilog typu zmiennego i nie może implikować rejestru fizycznego. W rejestrach wielobitowych dane są przechowywane w postaci liczb bez znaku i nie stosuje się rozszerzenia znaku.

Przykład -

reg c; // pojedyncza 1-bitowa zmienna rejestrowa

reg [5: 0] gem; // 6-bitowy wektor;

reg [6: 0] d, e; // dwie zmienne 7-bitowe

Wejście, wyjście, wejście

Te słowa kluczowe są używane do deklarowania portów wejściowych, wyjściowych i dwukierunkowych zadania lub modułu. Tutaj porty wejściowe i wejściowe, które są typu przewodowego, a port wyjściowy są skonfigurowane jako typu wire, reg, wand, wor lub tri. Zawsze domyślnie jest to typ przewodu.

Example

Module sample(a, c, b, d);  
Input c;   // An input where wire is used. 

Output a, b;  // Two outputs where wire is used. 
Output [2:0] d;  /* A three-bit output. One must declare type in a separate statement. */ 
reg [1:0] a;  // The above ‘a’ port is for declaration in reg.

Liczba całkowita

Liczby całkowite są używane w zmiennych ogólnego przeznaczenia. Są używane głównie w pętlach-wskaźnikach, stałych i parametrach. Są to dane typu „reg”. Przechowują dane jako podpisane liczby, podczas gdy jawnie zadeklarowane typy reg przechowują je jako dane bez znaku. Jeśli liczba całkowita nie jest zdefiniowana w czasie kompilacji, domyślny rozmiar będzie wynosił 32 bity.

Jeśli liczba całkowita posiada stałą, syntezator dostosowuje je do minimalnej szerokości potrzebnej w momencie kompilacji.

Example

Integer c;   // single 32-bit integer 
Assign a = 63;  // 63 defaults to a 7-bit variable.

Dostawa0, Dostawa1

Zasilanie0 definiuje przewody powiązane z logiką 0 (masa), a zasilanie1 definiuje przewody powiązane z logiką 1 (zasilanie).

Example

supply0 logic_0_wires; 
supply0 gnd1;  // equivalent to a wire assigned as 0 

supply1 logic_1_wires; 
supply1 c, s;

Czas

Czas to 64-bitowa wielkość, której można używać w połączeniu z zadaniem systemowym $ time do przechowywania czasu symulacji. Czas nie jest obsługiwany do syntezy i dlatego jest używany tylko do celów symulacji.

Example

time time_variable_list; 
time c; 
c = $time;   //c = current simulation time

Parametr

Parametr definiuje stałą, którą można ustawić podczas korzystania z modułu, co pozwala na dostosowanie modułu podczas procesu tworzenia instancji.

Example 
Parameter add = 3’b010, sub = 2’b11; 
Parameter n = 3; 
Parameter [2:0] param2 = 3’b110; 

reg [n-1:0] jam; /* A 3-bit register with length of n or above. */ 
always @(z) 
y = {{(add - sub){z}};  

if (z)
begin 
   state = param2[1];
else
   state = param2[2]; 
end

Operatorzy

Operatory arytmetyczne

Te operatory wykonują operacje arytmetyczne. + I −są używane jako operatory jednoargumentowe (x) lub binarne (z − y).

Operatory uwzględnione w operacji arytmetycznej to:

+ (dodawanie), - (odejmowanie), * (mnożenie), / (dzielenie),% (moduł)

Example -

parameter v = 5;
reg[3:0] b, d, h, i, count; 
h = b + d; 
i = d - v; 
cnt = (cnt +1)%16; //Can count 0 thru 15.

Operatorzy relacyjni

Te operatory porównują dwa operandy i zwracają wynik w postaci jednego bitu, 1 lub 0.

Zmienne wire i reg są dodatnie. Zatem (−3'd001) = = 3'd111 i (−3b001)> 3b110.

Operatory uwzględnione w operacji relacyjnej to:

  • == (równe)
  • ! = (różne od)
  • > (większe niż)
  • > = (większe lub równe)
  • <(mniej niż)
  • <= (mniejsze lub równe)

Example

if (z = = y) c = 1; 
   else c = 0; // Compare in 2’s compliment; d>b 
reg [3:0] d,b; 

if (d[3]= = b[3]) d[2:0] > b[2:0]; 
   else b[3]; 
Equivalent Statement 
e = (z == y);

Operatory bitowe

Operatory bitowe, które dokonują porównania bit po bicie między dwoma operandami.

Operatory, które są zawarte w operacji bitowej to:

  • & (bitowe AND)
  • | (bitowe LUB)
  • ~ (bitowe NIE)
  • ^ (bitowy XOR)
  • ~ ^ lub ^ ~ (bitowe XNOR)

Example

module and2 (d, b, c); 
input [1:0] d, b; 
output [1:0] c; 
assign c = d & b; 
end module

Operatory logiczne

Operatory logiczne są operatorami bitowymi i są używane tylko dla operandów jednobitowych. Zwracają wartość jednobitową, 0 lub 1. Mogą pracować na liczbach całkowitych lub grupach bitów, wyrażeniach i traktować wszystkie wartości niezerowe jako 1. Operatory logiczne są generalnie używane w instrukcjach warunkowych, ponieważ działają z wyrażeniami.

Operatory uwzględnione w operacji logicznej to -

  • ! (logiczne NIE)
  • && (logiczne AND)
  • || (logiczne LUB)

Example

wire[7:0] a, b, c; // a, b and c are multibit variables. 
reg x; 

if ((a == b) && (c)) x = 1; //x = 1 if a equals b, and c is nonzero. 
   else x = !a; // x =0 if a is anything but zero.

Operatory redukcji

Operatory redukcji są jednoargumentową postacią operatorów bitowych i działają na wszystkich bitach wektora operandu. Te również zwracają wartość jednobitową.

Operatory uwzględnione w operacji redukcji to:

  • & (redukcja AND)
  • | (redukcja LUB)
  • ~ & (redukcja NAND)
  • ~ | (redukcja NOR)
  • ^ (redukcja XOR)
  • ~ ^ lub ^ ~ (redukcja XNOR)

Example

Module chk_zero (x, z); 

Input [2:0] x; 
Output z; 
Assign z = & x; // Reduction AND 
End module

Operatorzy zmianowi

Operatory przesunięcia, które przesuwają pierwszy operand o liczbę bitów określoną przez drugi operand w składni. Wolne pozycje są wypełnione zerami dla obu kierunków, przesunięć w lewo i w prawo (nie ma rozszerzenia znaku użycia).

Operatory uwzględnione w operacji Shift to:

  • << (przesuń w lewo)
  • >> (przesuń w prawo)

Example

Assign z = c << 3; /* z = c shifted left 3 bits;

Wolne pozycje są wypełnione zerami * /

Operator łączenia

Operator konkatenacji łączy dwa lub więcej operandów w celu utworzenia większego wektora.

Operator zawarty w operacji konkatenacji to - {} (konkatenacja)

Example

wire [1:0] a, h; wire [2:0] x; wire [3;0] y, Z; 
assign x = {1’b0, a}; // x[2] = 0, x[1] = a[1], x[0] = a[0] 
assign b = {a, h}; /* b[3] = a[1], b[2] = a[0], b[1] = h[1], 
b[0] = h[0] */ 
assign {cout, b} = x + Z; // Concatenation of a result

Operator replikacji

Operator replikacji tworzy wiele kopii elementu.

Operator używany w operacji replikacji to - {n {element}} (n-krotna replikacja elementu)

Example

Wire [1:0] a, f; wire [4:0] x; 
Assign x = {2{1’f0}, a}; // Equivalent to x = {0,0,a } 
Assign y = {2{a}, 3{f}}; //Equivalent to y = {a,a,f,f} 
For synthesis, Synopsis did not like a zero replication.

For example:- 
Parameter l = 5, k = 5; 
Assign x = {(l-k){a}}

Operator warunkowy

Operator warunkowy syntetyzuje do multipleksera. Jest tego samego rodzaju, co jest używane w C / C ++ i oblicza jedno z dwóch wyrażeń na podstawie warunku.

Operator używany w operacji warunkowej to -

(Stan: schorzenie) ? (Wynik, jeśli warunek jest prawdziwy) -

(wynik, jeśli warunek fałszywy)

Example

Assign x = (g) ? a : b; 
Assign x = (inc = = 2) ? x+1 : x-1; 
/* if (inc), x = x+1, else x = x-1 */

Operandy

Literały

Literały to operandy o stałej wartości, które są używane w wyrażeniach Verilog. Dwa powszechnie używane literały Verilog to -

  • String - Operand literału ciągu to jednowymiarowa tablica znaków ujęta w podwójne cudzysłowy („”).

  • Numeric - Operand stałej liczby jest określony w postaci liczby binarnej, ósemkowej, dziesiętnej lub szesnastkowej.

Example

n - liczba całkowita reprezentująca liczbę bitów

F - jeden z czterech możliwych formatów podstawowych -

b - zapis binarny, o - ósemkowy, d - dziesiętny, h - szesnastkowy.

“time is”  // string literal 
267        // 32-bit decimal number 
2’b01      // 2-bit binary 
20’hB36F   // 20-bit hexadecimal number 
‘062       // 32-bit octal number

Przewody, rejestry i parametry

Przewody, rejestry i parametry to typy danych używane jako operandy w wyrażeniach Verilog.

Wybór bitu „x [2]” i wybór części „x [4: 2]”

Selekcja bitów i selekcja części służą do wybierania odpowiednio jednego bitu i wielu bitów z drutu, wektora reg lub parametru za pomocą nawiasów kwadratowych „[]”. Selekcje bitowe i selekcje części są również używane jako operandy w wyrażeniach w taki sam sposób, w jaki są używane ich główne obiekty danych.

Example

reg [7:0] x, y; 
reg [3:0] z; 
reg a; 
a = x[7] & y[7];      // bit-selects 
z = x[7:4] + y[3:0];  // part-selects

Połączenia funkcyjne

W wywołaniach funkcji zwracana wartość funkcji jest używana bezpośrednio w wyrażeniu bez konieczności przypisywania jej najpierw do rejestru lub przewodu. Po prostu umieszcza wywołanie funkcji jako jeden z typów operandów. Jest to potrzebne, aby upewnić się, że znasz szerokość bitową wartości zwracanej przez wywołanie funkcji.

Example  
Assign x = y & z & chk_yz(z, y); // chk_yz is a function 

. . ./* Definition of the function */ 
Function chk_yz; // function definition 
Input z,y; 
chk_yz = y^z; 
End function

Moduły

Deklaracja modułu

W Verilog moduł jest główną jednostką projektową. Wskazuje nazwę i listę portów (argumenty). Kilka następnych wierszy, które określają typ wejścia / wyjścia (wejście, wyjście lub inout) i szerokość każdego portu. Domyślna szerokość portu to tylko 1 bit. Zmienne portu muszą być zadeklarowane przez wire, wand. . ., rej. Domyślną zmienną portu jest wire. Zwykle wejścia są przewodowe, ponieważ ich dane są zablokowane poza modułem. Wyjścia są typu reg, jeśli ich sygnały są przechowywane w środku.

Example

module sub_add(add, in1, in2, out); 
input add; // defaults to wire 
input [7:0] in1, in2; wire in1, in2; 

output [7:0] out; reg out; 
... statements ... 
End module

Ciągłe przypisanie

Ciągłe przypisanie w module służy do przypisywania wartości do przewodu, co jest normalnym przypisaniem używanym na zewnątrz bloków zawsze lub początkowych. To przypisanie jest wykonywane za pomocą jawnej instrukcji przypisania lub w celu przypisania wartości do przewodu podczas jego deklaracji. Ciągłe przypisanie jest wykonywane w sposób ciągły w czasie symulacji. Kolejność instrukcji przypisania nie ma na to wpływu. Jeśli dokonasz jakiejkolwiek zmiany w dowolnym sygnale wejściowym po prawej stronie, zmieni to sygnał wyjściowy po lewej stronie.

Example

Wire [1:0] x = 2’y01;   // assigned on declaration 
Assign y = c | d;       // using assign statement 
Assign d = a & b; 
/* the order of the assign statements does not matter. */

Instancje modułów

Deklaracje modułów są szablonami do tworzenia rzeczywistych obiektów. Moduły są tworzone wewnątrz innych modułów, a każda instancja tworzy pojedynczy obiekt z tego szablonu. Wyjątkiem jest moduł najwyższego poziomu, który jest własną instancją. Porty modułu muszą być dopasowane do tych, które są zdefiniowane w szablonie. Jest określony -

  • By name, używając kropki „.template port name (nazwa przewodu podłączonego do portu)”. Lub

  • By position, umieszczając porty w tym samym miejscu na listach portów zarówno szablonu, jak i instancji.

Example

MODULE DEFINITION 
Module and4 (x, y, z); 
Input [3:0] x, y; 
Output [3:0] z; 
Assign z = x | y; 
End module

Modele behawioralne w Verilog zawierają instrukcje proceduralne, które kontrolują symulację i manipulują zmiennymi typów danych. Te wszystkie stwierdzenia są zawarte w procedurach. Z każdą procedurą jest powiązany przepływ czynności.

Podczas symulacji modelu behawioralnego wszystkie przepływy zdefiniowane przez instrukcje „zawsze” i „początkowe” rozpoczynają się razem w czasie symulacji „zero”. Instrukcje początkowe są wykonywane raz, a instrukcje always są wykonywane powtarzalnie. W tym modelu zmienne rejestru a i b są inicjalizowane odpowiednio na binarną 1 i 0 w czasie symulacji „zero”. Instrukcja początkowa jest wtedy zakończona i nie jest wykonywana ponownie podczas przebiegu symulacji. Ta instrukcja początkowa zawiera blok instrukcji początkowo-końcowych (nazywany również blokiem sekwencyjnym) instrukcji. W tym bloku typu początek-koniec najpierw inicjowana jest a, a następnie b.

Przykład modelowania behawioralnego

module behave; 
reg [1:0]a,b; 

initial 
begin 
   a = ’b1; 
   b = ’b0; 
end 

always 
begin 
   #50 a = ~a; 
end 

always 
begin 
   #100 b = ~b; 
end 
End module

Zadania proceduralne

Przypisania proceduralne służą do aktualizowania zmiennych reg, liczb całkowitych, czasu i pamięci. Istnieje znacząca różnica między przydziałem proceduralnym a przydziałem ciągłym, jak opisano poniżej -

Przypisania ciągłe sterują zmiennymi netto i są oceniane i aktualizowane za każdym razem, gdy argument wejściowy zmienia wartość.

Przypisania proceduralne aktualizują wartość zmiennych rejestrowych pod kontrolą konstrukcji przepływu proceduralnego, które je otaczają.

Prawa strona przypisania proceduralnego może być dowolnym wyrażeniem, którego wynikiem jest wartość. Jednak selekcje części po prawej stronie muszą mieć stałe indeksy. Lewa strona wskazuje zmienną, która otrzymuje przypisanie z prawej strony. Lewa strona zadania proceduralnego może przyjąć jedną z następujących form -

  • register, integer, real lub time variable - Przypisanie do odwołania do nazwy jednego z tych typów danych.

  • wybór bitu rejestru, zmiennej całkowitej, rzeczywistej lub czasu - Przypisanie do pojedynczego bitu, które pozostawia nietknięte inne bity.

  • częściowy wybór rejestru, zmiennej całkowitej, rzeczywistej lub czasowej - częściowy wybór dwóch lub większej liczby sąsiadujących ze sobą bitów, który pozostawia nietkniętą resztę bitów. W przypadku formularza wyboru części dozwolone są tylko wyrażenia stałe.

  • element pamięci - pojedyncze słowo pamięci. Należy zauważyć, że wybieranie bitów i wybieranie części jest niedozwolone w odniesieniach do elementów pamięci.

  • konkatenacja dowolnej z powyższych - można określić konkatenację dowolnej z czterech poprzednich form, co efektywnie dzieli wynik wyrażenia po prawej stronie i przypisuje części partycji w kolejności do różnych części konkatenacji.

Opóźnienie w przypisaniu (nie do syntezy)

W przypadku opóźnionego przypisania Δt jednostki czasu mijają, zanim instrukcja zostanie wykonana i wykonane zostanie przypisanie po lewej stronie. W przypadku opóźnienia wewnątrz przypisania prawa strona jest oceniana natychmiast, ale występuje opóźnienie Δt, zanim wynik zostanie umieszczony w przypisaniu po lewej stronie. Jeśli inna procedura zmienia sygnał po prawej stronie podczas Δt, nie ma to wpływu na wyjście. Opóźnienia nie są obsługiwane przez narzędzia syntezy.

Składnia

  • Procedural Assignmentzmienna = wyrażenie

  • Delayed assignment# Δt zmienna = wyrażenie;

  • Intra-assignment delayzmienna = # Δt wyrażenie;

Przykład

reg [6:0] sum; reg h, ziltch; 
sum[7] = b[7] ^ c[7]; // execute now. 
ziltch = #15 ckz&h; /* ckz&a evaluated now; ziltch changed 
after 15 time units. */ 

#10 hat = b&c; /* 10 units after ziltch changes, b&c is
evaluated and hat changes. */

Blokowanie przydziałów

Blokująca instrukcja przypisania proceduralnego musi zostać wykonana przed wykonaniem instrukcji następujących po niej w bloku sekwencyjnym. Blokująca instrukcja przypisania proceduralnego nie zapobiega wykonywaniu instrukcji, które następują po niej w bloku równoległym.

Składnia

Składnia blokującego przypisania proceduralnego jest następująca -

<lvalue> = <timing_control> <expression>

Gdzie lwartość jest typem danych, który jest prawidłowy dla instrukcji przypisania proceduralnego, = jest operatorem przypisania, a kontrola czasu to opcjonalne opóźnienie wewnątrz przypisania. Opóźnienie sterowania czasem może być sterowaniem opóźnieniem (na przykład # 6) lub sterowaniem zdarzeniem (na przykład @ (posedge clk)). Wyrażenie jest wartością po prawej stronie, którą symulator przypisuje lewej stronie. Operator = przypisanie używany do blokowania przypisań proceduralnych jest również używany przez ciągłe przypisania proceduralne i przydziały ciągłe.

Przykład

rega = 0; 
rega[3] = 1;            // a bit-select 
rega[3:5] = 7;          // a part-select 
mema[address] = 8’hff;  // assignment to a memory element 
{carry, acc} = rega + regb;  // a concatenation

Przypisania nieblokujące (RTL)

Nieblokujące przypisanie proceduralne umożliwia planowanie przydziałów bez blokowania przepływu procedur. Możesz skorzystać z nieblokującego oświadczenia proceduralnego, gdy chcesz wykonać kilka przypisań do rejestru w tym samym kroku czasowym, bez względu na kolejność lub wzajemne zależności.

Składnia

Składnia nieblokującego przypisania proceduralnego jest następująca -

<lvalue> <= <timing_control> <expression>

Gdzie lwartość jest typem danych, który jest prawidłowy dla instrukcji przypisania proceduralnego, <= jest nieblokującym operatorem przypisania, a kontrola taktowania to opcjonalna kontrola czasu wewnątrz przypisania. Opóźnienie sterowania czasem może być sterowaniem opóźnieniem lub sterowaniem zdarzeniem (na przykład @ (posedge clk)). Wyrażenie jest wartością po prawej stronie, którą symulator przypisuje lewej stronie. Nieblokujący operator przypisania jest tym samym operatorem, którego używa symulator dla mniej niż lub równorzędnego operatora relacyjnego. Symulator interpretuje operator <= jako operator relacyjny, gdy używasz go w wyrażeniu, i interpretuje operator <= jako operator przypisania, gdy używasz go w nieblokującej konstrukcji przypisania proceduralnego.

W jaki sposób symulator ocenia nieblokujące przypisania proceduralne Gdy symulator napotka nieblokujące przypisanie proceduralne, ocenia i wykonuje nieblokujące przypisanie proceduralne w dwóch krokach w następujący sposób -

  • Symulator ocenia prawą stronę i planuje przypisanie nowej wartości tak, aby miało miejsce w czasie określonym przez proceduralny element sterujący taktowaniem. Symulator ocenia prawą stronę i planuje przypisanie nowej wartości tak, aby miało miejsce w czasie określonym przez proceduralny element sterujący taktowaniem.

  • Na końcu kroku czasowego, w którym upłynęło dane opóźnienie lub nastąpiło odpowiednie zdarzenie, symulator wykonuje przypisanie, przypisując wartość lewej stronie.

Przykład

module evaluates2(out); 
output out; 
reg a, b, c; 
initial 

begin 
   a = 0; 
   b = 1; 
   c = 0; 
end 
always c = #5 ~c; 
always @(posedge c) 

begin 
   a <= b; 
   b <= a; 
end 
endmodule

Warunki

Instrukcja warunkowa (lub instrukcja if-else) służy do podjęcia decyzji, czy instrukcja zostanie wykonana, czy nie.

Formalnie składnia jest następująca -

<statement> 
::= if ( <expression> ) <statement_or_null> 
||= if ( <expression> ) <statement_or_null> 
   else <statement_or_null> 
<statement_or_null> 

::= <statement> 
||= ;

Oceniane jest <wyrażenie>; jeśli to prawda (to znaczy ma znaną wartość niezerową), wykonywana jest pierwsza instrukcja. Jeśli jest fałszywe (ma wartość zerową lub wartość to x lub z), pierwsza instrukcja nie jest wykonywana. Jeśli istnieje instrukcja else i <expression> ma wartość false, wykonywana jest instrukcja else. Ponieważ wartość liczbowa wyrażenia if jest testowana na zero, możliwe są pewne skróty.

Na przykład następujące dwie instrukcje wyrażają tę samą logikę -

if (expression) 
if (expression != 0)

Ponieważ część else if-else jest opcjonalna, może dojść do zamieszania, gdy w zagnieżdżonej sekwencji if zostanie pominięte słowo else. Rozwiązuje się to poprzez zawsze kojarzenie else z najbliższym poprzednim, jeśli brakuje mu innego.

Przykład

if (index > 0) 
if (rega > regb) 
   result = rega; 
   else // else applies to preceding if 
   result = regb; 

If that association is not what you want, use a begin-end block statement 
to force the proper association 

if (index > 0) 
begin 

if (rega > regb) 
result = rega; 
end 
   else 
   result = regb;

Konstrukcja: if- else- if

Poniższa konstrukcja pojawia się na tyle często, że warto ją pokrótce omówić.

Example

if (<expression>) 
   <statement> 
   else if (<expression>) 
   <statement> 
   else if (<expression>) 
   <statement> 
   else  
   <statement>

Ta sekwencja if (znana jako konstrukcja if-else-if) jest najbardziej ogólnym sposobem pisania decyzji wielostronnej. Wyrażenia są oceniane w kolejności; jeśli jakieś wyrażenie jest prawdziwe, wykonywana jest instrukcja z nim związana, a to kończy cały łańcuch. Każda instrukcja jest pojedynczą instrukcją lub blokiem instrukcji.

Ostatnia część else konstrukcji if-else-if obsługuje przypadek „żaden z powyższych” lub domyślny, gdy żaden z pozostałych warunków nie został spełniony. Czasami nie ma wyraźnej akcji domyślnej; w takim przypadku końcowe else można pominąć lub użyć go do sprawdzenia błędów w celu wykrycia niemożliwego warunku.

Instrukcja Case

Instrukcja case jest specjalną wielostronną instrukcją decyzyjną, która sprawdza, czy wyrażenie pasuje do jednego z wielu innych wyrażeń i odpowiednio rozgałęzia się. Instrukcja case jest przydatna do opisania, na przykład, dekodowania instrukcji mikroprocesora. Instrukcja case ma następującą składnię -

Example

<statement> 
::= case ( <expression> ) <case_item>+ endcase 
||= casez ( <expression> ) <case_item>+ endcase 
||= casex ( <expression> ) <case_item>+ endcase 
<case_item> 
::= <expression> <,<expression>>* : <statement_or_null> 
||= default : <statement_or_null> 
||= default <statement_or_null>

Wyrażenia przypadków są oceniane i porównywane w dokładnej kolejności, w jakiej zostały podane. Jeśli podczas wyszukiwania liniowego jedno z wyrażeń pozycji sprawy pasuje do wyrażenia w nawiasach, wykonywana jest instrukcja powiązana z tą pozycją sprawy. Jeśli wszystkie porównania zakończą się niepowodzeniem i zostanie podana pozycja domyślna, wykonywana jest instrukcja pozycji domyślnej. Jeśli nie podano domyślnej instrukcji, a wszystkie porównania zakończą się niepowodzeniem, żadna z instrukcji pozycji przypadku nie zostanie wykonana.

Oprócz składni instrukcja case różni się od wieloczynnikowej konstrukcji if-else-if na dwa ważne sposoby -

  • Wyrażenia warunkowe w konstrukcji if-else-if są bardziej ogólne niż porównywanie jednego wyrażenia z kilkoma innymi, jak w przypadku instrukcji case.

  • Instrukcja case zapewnia ostateczny wynik, gdy w wyrażeniu występują wartości x i z.

Instrukcje pętli

Istnieją cztery typy instrukcji zapętlających. Umożliwiają one kontrolowanie wykonania instrukcji zero, jeden lub więcej razy.

  • forever bez przerwy wykonuje polecenie.

  • Powtórz wykonuje instrukcję określoną liczbę razy.

  • while wykonuje instrukcję, dopóki wyrażenie nie stanie się fałszywe. Jeśli wyrażenie zaczyna się jako fałsz, instrukcja nie jest w ogóle wykonywana.

  • do kontroli wykonywania powiązanych instrukcji w trzystopniowym procesie, jak następuje:

    • Wykonuje przypisanie zwykle używane do inicjalizacji zmiennej, która kontroluje liczbę wykonywanych pętli

    • Oblicza wyrażenie - jeśli wynik jest równy zero, pętla for kończy działanie, a jeśli nie jest zerem, pętla for wykonuje skojarzone z nią instrukcje, a następnie wykonuje krok 3

    • Wykonuje przypisanie zwykle używane do modyfikowania wartości zmiennej loopcontrol, a następnie powtarza krok 2

Poniżej przedstawiono reguły składni instrukcji pętli -

Example

<statement> 
::= forever <statement> 
||=forever 
begin 
   <statement>+ 
end  

<Statement> 
::= repeat ( <expression> ) <statement> 
||=repeat ( <expression> ) 
begin
   <statement>+ 
end  

<statement> 
::= while ( <expression> ) <statement> 
||=while ( <expression> ) 
begin 
   <statement>+ 
end  
<statement> 
::= for ( <assignment> ; <expression> ; <assignment> ) 
<statement> 
||=for ( <assignment> ; <expression> ; <assignment> ) 
begin 
   <statement>+ 
end

Kontrola opóźnień

Kontrola opóźnienia

Wykonanie instrukcji proceduralnej może być kontrolowane z opóźnieniem przy użyciu następującej składni -

<statement> 
::= <delay_control> <statement_or_null> 
<delay_control> 
::= # <NUMBER> 
||= # <identifier> 
||= # ( <mintypmax_expression> )

Poniższy przykład opóźnia wykonanie zadania o 10 jednostek czasu -

# 10 rega = regb;

W następnych trzech przykładach podano wyrażenie następujące po znaku liczby (#). Wykonanie przypisania opóźnia się o czas symulacji określony przez wartość wyrażenia.

Kontrola zdarzeń

Wykonanie instrukcji proceduralnej można zsynchronizować ze zmianą wartości w sieci lub rejestrze albo wystąpieniem zadeklarowanego zdarzenia, korzystając z następującej składni sterowania zdarzeniami -

Example

<statement> 
::= <event_control> <statement_or_null> 

<event_control> 
::= @ <identifier> 
||= @ ( <event_expression> ) 

<event_expression> 
::= <expression> 
||= posedge <SCALAR_EVENT_EXPRESSION> 
||= negedge <SCALAR_EVENT_EXPRESSION> 
||= <event_expression> <or <event_expression>>

* <SCALAR_EVENT_EXPRESSION> jest wyrażeniem, którego wynikiem jest wartość jednobitowa.

Zmiany wartości w sieciach i rejestrach mogą służyć jako zdarzenia wyzwalające wykonanie instrukcji. Nazywa się to wykrywaniem niejawnego zdarzenia. Składnia Verilog umożliwia również wykrycie zmiany na podstawie kierunku zmiany - to znaczy w kierunku wartości 1 (posedge) lub w kierunku wartości 0 (negedge). Zachowanie posedge i negedge dla nieznanych wartości wyrażenia jest następujące -

  • negedge jest wykrywany przy przejściu z 1 do nieznanego iz nieznanego do 0
  • pozedge jest wykrywany przy przejściu od 0 do nieznanego iz nieznanego do 1

Procedury: zawsze i początkowe bloki

Wszystkie procedury w Verilog są określone w jednym z następujących czterech bloków. 1) Bloki początkowe 2) Zawsze bloki 3) Zadanie 4) Funkcja

Instrukcje początkowe i always są włączane na początku symulacji. Początkowe bloki są wykonywane tylko raz, a jego aktywność kończy się po zakończeniu instrukcji. W przeciwieństwie do tego, zawsze bloki są wykonywane wielokrotnie. Jego aktywność zanika dopiero po zakończeniu symulacji. Nie ma ograniczeń co do liczby początkowych i zawsze bloków, które można zdefiniować w module. Zadania i funkcje to procedury, które są włączane z jednego lub kilku miejsc w innych procedurach.

Bloki początkowe

Składnia początkowej instrukcji jest następująca -

<initial_statement> 
::= initial <statement>

Poniższy przykład ilustruje użycie instrukcji początkowej do inicjalizacji zmiennych na początku symulacji.

Initial 
Begin 
   Areg = 0; // initialize a register 
   For (index = 0; index < size; index = index + 1) 
   Memory [index] = 0; //initialize a memory 
   Word 
End

Innym typowym zastosowaniem początkowych bloków jest specyfikacja opisów przebiegów, które są wykonywane raz w celu dostarczenia bodźca do głównej części symulowanego obwodu.

Initial 
Begin 
   Inputs = ’b000000; 
   // initialize at time zero 
   #10 inputs = ’b011001; // first pattern 
   #10 inputs = ’b011011; // second pattern 
   #10 inputs = ’b011000; // third pattern 
   #10 inputs = ’b001000; // last pattern 
End

Zawsze blokuje

Instrukcja „always” powtarza się w sposób ciągły przez cały przebieg symulacji. Składnia instrukcji always jest podana poniżej

<always_statement> 
::= always <statement>

Instrukcja „always”, ze względu na swoją zapętloną naturę, jest użyteczna tylko w połączeniu z jakąś formą kontroli czasu. Jeśli instrukcja „always” nie zapewnia czasu na przejście do przodu, instrukcja „always” tworzy warunek zakleszczenia symulacji. Na przykład poniższy kod tworzy nieskończoną pętlę z zerowym opóźnieniem -

Always areg = ~areg;

Zapewnienie kontroli czasu w powyższym kodzie tworzy potencjalnie przydatny opis - jak w poniższym przykładzie -

Always #half_period areg = ~areg;