.. _w06-clock: ========================== WykĹad 6: SygnaĹy zegarowe ========================== Data: 24.11.2020, 01.12.2020 .. toctree:: .. contents:: O sygnaĹach zegarowych ====================== SygnaĹem zegarowym nazywamy sygnaĹ nadajÄ cy tempo pracy ukĹadu. W logice synchronicznej jest to sygnaĹ, ktĂłrego zbocze powoduje rozpoczÄcie jednego cyklu pracy czÄĹci ukĹadu (zwanego domenÄ zegarowÄ ) â przerzutniki przechowujÄ ce stan ukĹadu otrzymujÄ nowe wartoĹci, synchroniczne porty odczytu pamiÄci wykonujÄ odczyt, portu zapisu wykonujÄ zapis, po czym kombinacyjna czÄĹÄ ukĹadu rozpoczyna obliczenia ktĂłrych wyniki zostanÄ wykorzystane przy nastÄpnym aktywnym zboczu zegara. Zazwyczaj aktywnym zboczem zegara jest zbocze rosnÄ ce (tranzycja z 0 na 1), choÄ rĂłwnie dobrze moĹźe to byÄ zbocze malejÄ ce (tranzycja z 1 na 0) â ukĹady FPGA zazwyczaj obsĹugujÄ te opcje rĂłwnoprawnie. W niektĂłrych ukĹadach moĹźna spotkaÄ przerzutniki, w ktĂłrych oba zbocza jednoczeĹnie mogÄ byÄ aktywne, lecz jest to doĹÄ ezoteryczna rzadkoĹÄ. Zazwyczaj jako sygnaĹu zegarowego uĹźywa siÄ prostego sygnaĹu okresowego pochodzÄ cego z oscylatora â zbocza zegara nastÄpujÄ wtedy zawsze w staĹych odstÄpach. Nie jest to jednak wymaganie â w przypadku "zwykĹej" logiki synchronicznej nic nie stoi na przeszkodzie, by sygnaĹ zegarowy byĹ doĹÄ dowolny. MoĹźliwe jest zatrzymanie zegara na dowolnie dĹugi czas, zmienny odstÄp pomiÄdzy zboczami, itp. Jedyne wymagania, jakie musimy zachowaÄ to: - minimalny okres zegara (czas pomiÄdzy kolejnymi aktywnymi zboczami) â wymagana minimalna wartoĹÄ jest wyznaczana przez narzÄdzia P&R na podstawie opóźnienia najdĹuĹźszej ĹcieĹźki kombinacyjnej w naszym ukĹadzie (plus czasy setup i hold), a jej odwrotnoĹÄ jest maksymalnÄ czÄstotliwoĹciÄ zegara jakiej moĹźemy uĹźyÄ - minimalny czas wysoki i niski â gdy zegar zmienia stan z 0 na 1, musi pozostaÄ w stanie 1 przez minimalny czas wysoki (podany w dokumentacji przerzutnika, RAMu, DSP, czy innych prymitywĂłw w naszej technologii); analogicznie dziaĹa minimalny czas niski; w praktyce jest to maĹo waĹźne ograniczenie o ile nasz sygnaĹ zegarowy jest generowany w sensowny sposĂłb (praktycznie na pewno najpierw bÄdziemy mieÄ problem z minimalnym okresem zegara) MoĹźliwoĹÄ zatrzymania zegara bez szkody dla ukĹadu jest bardzo przydatna i czÄsto stosowana: - w celu ograniczenia poboru prÄ du przez ukĹad â zatrzymanie zegara kasuje caĹe dynamiczne zuĹźycie prÄ du przez zatrzymanÄ czÄĹÄ ukĹadu - w celu debugowania ukĹadu (choÄ to jest bardzo skomplikowana sprawa) MoĹźliwe jest teĹź uĹźycie wyjĹcia ukĹadu synchronicznego (wyjĹcia przerzutnika) jako sygnaĹu zegarowego dla innego ukĹadu synchronicznego. Rzadko jest to jednak dobry pomysĹ (lepiej uĹźyÄ specjalistycznego prymitywu do kontroli zegara) â praktycznie jedynym przypadkiem, gdzie ma to sens sÄ róşnego rodzaju wolne interfejsy wejĹcia / wyjĹcia: SPI, JTAG, I2C, itp. NiektĂłre specjalistyczne ukĹady (nazywa siÄ je ukĹadami dynamicznymi) majÄ ĹciĹlejsze wymagania co do sygnaĹu zegarowego â wymagajÄ staĹego okresu, bÄ dĹş teĹź po prostu nie pozwalajÄ na zatrzymanie zegara dĹuĹźej niĹź przez okreĹlony czas. PrzykĹadami sÄ opisane dalej ukĹady przeksztaĹcajÄ ce sygnaĹy zegarowe bÄ dĹş szybkie interfejsy wejĹcia/wyjĹcia. Parametry sygnaĹu okresowego ---------------------------- JeĹli nasz sygnaĹ zegarowy jest zwykĹym sygnaĹem okresowym (a nie czymĹ generowanym rÄcznie przez ukĹad logiczny), opisujemy go za pomocÄ nastÄpujÄ cych parametrĂłw: 1. Okres (period) â czas miÄdzy kolejnymi zboczami rosnÄ cymi, mierzony w ns, bÄ dĹş czÄstotliwoĹÄ zegara (odwrotnoĹÄ okresu, mierzona w MHz). 2. WypeĹnienie (duty cycle) â czÄĹÄ okresu zegara, przez ktĂłry jego wartoĹciÄ jest 1, mierzone w %. Zazwyczaj uĹźywa siÄ zegarĂłw o wypeĹnieniu 50%, lecz zdarzajÄ siÄ inne wartoĹci, szczegĂłlnie przy prostych dzielnikach czÄstotliwoĹci. 3. Wahania (jitter) â miara niedoskonaĹoĹci zegara, czyli tego, jak bardzo dĹugoĹÄ kolejnych okresĂłw róşni siÄ od siebie; mierzone w ps lub w % okresu. Zdarza siÄ rozróşniaÄ wahania krĂłtkoterminowe (róşnica dĹugoĹci okresĂłw w oknie czasowym kilku okresĂłw) i dĹugoterminowe (jak bardzo dĹugoĹÄ okresĂłw róşni siÄ od siebie na przestrzeni sekund). Musimy go odliczaÄ od dĹugoĹci okresu przy analizie czasowej, by zapewniÄ poprawne dziaĹanie ukĹadu. 4. Faza (phase) â przesuniÄcie poczÄ tku okresu w czasie. To pojÄcie ma sens tylko w przypadku grupy zsynchronizowanych zegarĂłw, gdzie mĂłwimy o ich wzajemnych relacjach. Jest zazwyczaj mierzona w stopniach, rzadziej w ns. JeĹli mamy dwa sygnaĹy zegarowe o tym samym okresie i fazach 0° i 90°, znaczy to, Ĺźe drugi sygnaĹ jest opóźniony o 1/4 okresu w stosunku do pierwszego. JeĹli mamy sygnaĹy o fazie 0° i 180° oraz wypeĹnieniu 50%, oznacza to, Ĺźe drugi jest efektywnie zanegowanÄ wersjÄ pierwszego. O fazie moĹźna teĹź mĂłwiÄ w przypadku zegarĂłw, ktĂłrych wspĂłĹczynnik czÄstotliwoĹci jest prostym uĹamkiem (np. 20MHz i 30MHz), lecz naleĹźy wtedy bardzo uwaĹźaÄ na stosowane definicje. Generatory sygnaĹĂłw zegarowych ------------------------------ Okazuje siÄ, Ĺźe technologia w ktĂłrej wytwarzane sÄ ukĹady cyfrowe nie pozwala na generowanie zegarĂłw dobrej jakoĹci â w kaĹźdym ukĹadzie majÄ cym nietrywialne wymagania co do zegara stosuje siÄ zewnÄtrzny generator sygnaĹu zegarowego. Okazuje siÄ jednak, Ĺźe gdy juĹź mamy sygnaĹ zegarowy dobrej jakoĹci, moĹźemy doĹÄ Ĺatwo przeksztaĹciÄ go w dobry sygnaĹ zegarowy o innych parametrach. Istnieje wiele sposobĂłw na wygenerowanie sygnaĹu zegarowego. WspomnÄ tutaj o trzech: - oscylator pierĹcieniowy (ring oscillator) - oscylator LC - oscylator kwarcowy Naprostszym typem oscylatora jest oscylator pierĹcieniowy â jest to po prostu nieparzysta liczba bramek logicznych NOT poĹÄ czona w pierĹcieĹ. Jego czÄstotliwoĹÄ to 1 / (suma opóźnieĹ bramek i poĹÄ czeĹ miÄdzy nimi). Jest to bardzo niedokĹadny oscylator (rzÄdu Âą30% róşnicy dĹugoĹci okresu, zaleĹźnie od temperatury, napiÄcia zasilania i róşnic powstaĹych w procesie fotolitografii) i nie powinien byÄ stosowany w jakiejkolwiek sytuacji wymagajÄ cej konkretnej czÄstotliwoĹci pracy, ale bywa uĹźywany gdy potrzebny jest po prostu *jakiĹ* zegar. PrzykĹadem oscylatora pierĹcieniowego jest wewnÄtrzny zegar konfiguracyjny ukĹadu FPGA (jeĹli zostaĹ wybrany tryb konfiguracji w ktĂłrym to FPGA generuje sygnaĹ zegarowy). .. warning:: Nie naleĹźy prĂłbowaÄ tworzyÄ wĹasnego oscylatora pierĹcieniowego uĹźywajÄ c programowalnej logiki â nie mamy wystarczajÄ cej kontroli nad uĹoĹźeniem i poĹÄ czeniem ukĹadu, by sensownie kontrolowaÄ czÄstotliwoĹÄ. TrochÄ bardziej skomplikowanym generatorem jest generator LC, w ktĂłrym uĹźywamy rezonansu ukĹadu zĹóşonego z kondensatora i cewki do wygenerowania zegara. CzÄstotliwoĹciÄ takiego zegara jest ``1/(tau * sqrt(L*C))``. WciÄ Ĺź, jest to zegar nieco niedokĹadny (ma wahania rzÄdu Âą1%) i nie moĹźe byÄ uĹźywany w wielu interfejsach wejĹcia/wyjĹcia (jeĹli np. uĹźyjemy go do wygenerowania sygnaĹu VGA, obraz bÄdzie siÄ dosĹownie trzÄ sĹ na monitorze). Do generowania sensownie dokĹadnych (Âą0.001% wahaĹ) zegarĂłw w elektronice uĹźywa siÄ oscylatorĂłw kwarcowych, ktĂłre uĹźywajÄ wibracji krysztaĹu kwarcowego do generowania sygnaĹu zegarowego. DziÄki elektronicznym ukĹadom przeksztaĹcajÄ cym sygnaĹy zegarowe (PLL), czÄsto wystarcza jeden krysztaĹ (zazwyczaj o czÄstotliwoĹci rzÄdu 10MHz-100MHz) do wygenerowania dowolnej liczby sygnaĹĂłw zegarowych o dowolnych wartoĹciach. Dystrybucja sygnaĹĂłw zegarowych ------------------------------- W ukĹadach cyfrowych bardzo poĹźÄ dane jest, by zbocza sygnaĹu zegarowego dochodziĹy jednoczeĹnie do wszystkich przerzutnikĂłw, ktĂłrymi sterujÄ . Róşnica w czasie przyjĹcia zbocza do róşnych miejsc nazywa siÄ clock skew i powoduje szereg problemĂłw: - jeĹli suma clock skew i czasu hold jest wiÄksza niĹź czas propagacji miÄdzy wyjĹciem jednego przerzutnika a wejĹciem drugiego, mamy naruszenie czasu hold i nasz ukĹad nie bÄdzie dziaĹaÄ - clock skew efektywnie dodaje siÄ do wielu czasĂłw propagacji, zmniejszajÄ c maksymalnÄ moĹźliwÄ czÄstotliwoĹÄ zegara Aby zminimalizowaÄ clock skew, w ukĹadach FPGA (i ASIC) istniejÄ specjalne sieci dystrybucji sygnaĹĂłw zegarowych, zaprojektowane tak, by dĹugoĹÄ ĹcieĹźki od ĹşrĂłdĹa sygnaĹu do przerzutnikĂłw byĹa mniej-wiÄcej staĹa. W ukĹadach Xilinx 7 Series mamy 32 bufory globalne, bÄdÄ ce ĹşrĂłdĹami takich sieci. NarzÄdzia do syntezy same wywnioskujÄ , ktĂłre z naszych sygnaĹĂłw powinny uĹźywaÄ buforĂłw globalnych, ale jeĹli chcemy, moĹźemy poprosiÄ o to jawnie przez zinstancjonowanie prymitywu ``BUFG``. DostÄpne jest rĂłwnieĹź wiele buforĂłw regionalnych (obejmujÄ cych tylko czÄĹÄ ukĹadu, za to z mniejszym opóźnieniem), ale nie bÄdziemy siÄ nimi zajmowaÄ. Co wiÄcej, bufory globalne potrafiÄ rĂłwnieĹź peĹniÄ rolÄ przeĹÄ cznika miÄdzy dwoma rĂłznymi ĹşrĂłdĹami zegara (prymityw ``BUFGMUX`` lub ``BUFGCTRL``) â przydaje siÄ to, gdy bÄdziemy projektowaÄ ukĹad, ktĂłry powinien dziaĹaÄ na róşnych czÄstotliwoĹciach (tryb turbo, interfejsy sprzÄtowe majÄ ce wolne/szybkie wersje, róşne rozdzielczoĹci VGA, itp). PrzeĹÄ cznik ten jest doĹÄ skomplikowany â bezpieczne przeĹÄ czenie sygnaĹu zegarowego miÄdzy dwoma ĹşrĂłdĹami wymaga duĹźej ostroĹźnoĹci, by nie naruszyÄ wymagaĹ minimalnego czasu niskiego/wysokiego i nie naleĹźy prĂłbowaÄ tego robiÄ rÄcznie. Specjalnym (i bardzo czÄstym) przypadkiem funkcjonalnoĹci przeĹÄ czania zegara jest moĹźliwoĹÄ wyĹÄ czenia go (czyli przeĹÄ czania siÄ miÄdzy naszym ĹşrĂłdĹem zegara a sygnaĹem stale rĂłwnym zero) â takÄ funkcjonalnoĹÄ realizuje prymityw ``BUFGCE``:: # UkĹad w domenie sterowanej przez clk_with_enable bÄdzie synchroniczny # z domenÄ sterowanÄ przez clk_bypass, ale bÄdzie wykonywaĹ pracÄ tylko, # gdy sig_enable bÄdzie prawdÄ â odbywa siÄ to przez maskowanie sygnaĹu # zegarowego. m.submodules.buf_a = Instance("BUFG", i_I=clk_orig, o_O=clk_bypass, ) m.submodules.buf_b = Instance("BUFGCE", i_I=clk_orig, i_CE=sig_enable, o_O=clk_with_enable, ) # Uwaga: aby te domeny byĹy poprawnie zsynchronizowane, konieczne jest # uĹźycie BUFG na clk_bypass, by zapewniÄ takie same opóźnienia dystrybucji # zegara. Przetwarzanie sygnaĹĂłw zegarowych --------------------------------- Technologia produkcji ukĹadĂłw cyfrowych nie pozwala na generowanie sygnaĹĂłw zegarowych dobrej jakoĹci wewnÄ trz naszego ukĹadu. Okazuje siÄ jednak, Ĺźe majÄ c juĹź taki sygnaĹ z zewnÄ trz (np. z oscylatora kwarcowego) moĹźna wyprodukowaÄ ukĹad przetwarzajÄ cy go w sygnaĹ zegarowy dobrej jakoĹci o innych parametrach. Takim ukĹadem jest PLL (phase locked loop). Istnieje bardzo wiele rodzajĂłw ukĹadĂłw PLL (wystÄpujÄ cych pod róşnymi nazwami), a ich uĹźycie zawsze wymaga bezpoĹredniego uĹźycia doĹÄ skomplikowanych prymitywĂłw zaleĹźnych od producenta i konkretnej technologii FPGA. Takie ukĹady majÄ jednak doĹÄ podobny ogĂłlny schemat dziaĹania: 1. PLL ma wejĹcie zegarowe (nazwijmy je ``CLKIN``), do ktĂłrego podĹÄ czamy otrzymany skÄ dĹ bazowy sygnaĹ zegarowy. 2. PLL zawiera oscylator o regulowalnej czÄstotliwoĹci (zazwyczaj nazywany VCO â voltage controlled oscillator). VCO generuje jakiĹ sygnaĹ zegarowy (zazwyczaj duĹźej czÄstotliwoĹci â w przypadku Xilinxa zakres to 800 â 1600MHz), ktĂłry jest wejĹciem do kilku dzielnikĂłw. 3. PLL zawiera kilka (2-8) programowalnych dzielnikĂłw zegara, ktĂłre produkujÄ z wyjscia VCO nowe sygnaĹy zegarowe, ktĂłrych czÄstotliwoĹÄ to czÄstotliwoĹÄ VCO podzielona przez jakÄ Ĺ niezbyt duĹźÄ staĹÄ caĹkowitÄ (nazwijmy je ``DIV<idx>``). Te dzielniki majÄ teĹź zazwyczaj moĹźliwoĹÄ kontrolowania wypeĹnienia i relatywnej fazy wyjĹÄ. SygnaĹy zegarowe generowane przez dzielniki sÄ wyjĹciami PLLa (nazwijmy je ``CLKOUT<idx>``. 4. PLL ma drugie wejĹcie zegarowe (nazwijmy je ``CLKFB``), do ktĂłrego naleĹźy podĹÄ czyÄ wyjĹcie ``CLKOUT0`` poprzez sieÄ dystrybucji zegara â tÄ samÄ (bÄ dĹş wystarczajÄ co podobnÄ ), co ewentualni uĹźytkownicy sygnaĹĂłw wyjĹciowych. 5. PLL zawiera ukĹad porĂłwnywania fazy (phase comparator), ktĂłry caĹy czas porĂłwnuje wejĹcie ``CLKFB`` z wejĹciem ``CLKIN`` i tak steruje szybkoĹciÄ VCO, by wyrĂłwnaÄ te wejĹcia w czÄstotliwoĹci i w fazie. VCO poczÄ tkowo generuje sygnaĹ wyjĹciowy o kompletnie nieprzewidywalnych parametrach. UkĹad porĂłwnywania fazy jednak stopniowo poprawia czÄstotliwoĹÄ oraz fazÄ VCO tak, by ``CLKFB`` (czyli sygnaĹ wygenerowany przez VCO podzielony przez ``DIV0``) staĹ siÄ identyczny z ``CLKIN``. Gdy to nastÄ pi, PLL nazywa siÄ zablokowanym (locked) â od tego momentu, ukĹad porĂłwnywania fazy ciÄ gle monitoruje te dwa sygnaĹy i likwiduje najdrobniejsze odchylenia, a wygenerowany sygnaĹ zgadza siÄ co do cyklu z wejĹciem tak dĹugo, jak dĹugo wejĹcie jest stabilne (nie zostanie wyĹaczone i nie zmieni znaczÄ co swojej czÄstotliwoĹci). 6. PLL ma wyjĹcie ``LOCKED``, ktĂłre mĂłwi czy PLL osiÄ gnaĹ juĹź stan locked. 7. PLL ma wejĹcie ``RESET``, ktĂłre rozpoczyna od nowa procedurÄ dostosowywania VCO do wejĹcia ``CLKIN``. Powinno siÄ go uĹźyÄ, gdy ĹşrĂłdĹo sygnaĹu wejĹciowego ulega zmianie. SygnaĹ ``CLKOUT0`` jest de facto rĂłwny sygnaĹowi ``CLKIN`` przesuniÄtemu w fazie do tyĹu o tyle, ile wynosi opóźnienie dystrybucji zegara miÄdzy ``CLKOUT0`` a ``CLKFB`` â pozwala to efektywnie zniwelowaÄ opóźnienie dystrybucji w naszym ukĹadzie FPGA i sprawiÄ, Ĺźe zegar na wejĹciu naszych przerzutnikĂłw bÄdzie wyrĂłwnany z zegarem na wejĹciu naszego caĹego ukĹadu, co przydaje siÄ gdy chcemy przesyĹaÄ dane synchronicznie z innymi ukĹadami na pĹytce drukowanej. Znacznie ciekawszymi sygnaĹami sÄ jednak pozostaĹe wyjĹcia ``CLKOUT<idx>`` â zauwaĹźmy, Ĺźe sÄ wygenerowane z tego samego VCO co ``CLKOUT0`` przez proste dzielniki zegara, a zatem sÄ wyrĂłwnane do ``CLKIN`` z prostym wspĂłĹczynnikiem czÄstotliwoĹci. Na przykĹad: - ``CLKIN`` ma czÄstotliwoĹÄ 50MHz - ``DIV0`` wynosi 16 - ``DIV1`` wynosi 12 - VCO ustabilizuje siÄ na czÄstotliwoĹci ``CLKIN * DIV0``, czyli 800MHz - ``CLKOUT0`` bÄdzie miaĹ czÄstotliwoĹÄ ``VCO / DIV0``, czyli 50MHz (jak ``CLKIN`` przez pÄtlÄ sprzÄĹźenia zwrotnego) - ``CLKOUT1`` bÄdzie miaĹ czÄstotliwoĹÄ ``VCO / DIV1 (= CLKIN * DIV0 / DIV1)``, czyli 66MHz Oznacza to, Ĺźe nasz ukĹad PLL efektywnie mnoĹźy czÄstotliwoĹÄ wejĹcia przez ``DIV0 / DIV1`` produkujÄ c wyjĹcie ``CLKOUT1`` â za pomocÄ PLLi moĹźemy wiÄc uzyskaÄ w miarÄ dowolne czÄstotliwoĹci mnoĹźÄ c wejĹcie przez odpowiednie uĹamki (choÄ trzeba ostroĹźnie dobieraÄ parametry tak, by zmieĹciÄ siÄ w wymaganiach PLLa). W ukĹadach Xilinx 7 Series mamy dostÄpne dwa rodzaje ukĹadĂłw PLL: - prymityw ``MMCME2_BASE`` bÄ dĹş ``MMCE2_ADV`` â trochÄ prostsza wersja - prymityw ``PLLE2_BASE`` bÄ dĹş ``PLLE2_ADV`` â ma wiÄcej funkcjonalnoĹci Wersje ``_ADV`` pozwalajÄ na rekonfiguracjÄ parametrĂłw w trakcie dziaĹania ukĹadu. Po opis uĹźycia tych ukĹadĂłw odsyĹam do dokumentacji: https://www.xilinx.com/support/documentation/user_guides/ug472_7Series_Clocking.pdf Domeny zegarowe w nMigen ======================== W nMigen sygnaĹy zegarowe sÄ w wiÄkszoĹci niejawne â sÄ propagowane przez ukĹad w ramach obiektu typu ``ClockDomain``, reprezentujÄ cego domenÄ zegarowÄ . DomyĹlnie istnieje jedna domena zegarowa o nazwie ``sync``, ale moĹźemy stworzyÄ ich wiÄcej. Domena zegarowa (``ClockDomain``) to obiekt opakowujÄ cy nastÄpujÄ ce elementy: - sygnaĹ zegarowy: jednobitowy sygnaĹ sterujÄ cy pracÄ tej domeny - wybĂłr aktywnego zbocza zegara (rosnÄ ce lub malejÄ ce; domyĹlnie rosnÄ ce) - sygnaĹ resetu: opcjonalny jednobitowy sygnaĹ, ktĂłrego ustawienie na 1 spowoduje ustawienie wszystkich rejestrĂłw w domenie na wartoĹÄ poczÄ tkowÄ - typ sygnaĹu resetu: synchroniczny (reset nastÄpuje na aktywnym zboczu zegara jeĹli sygnaĹ resetu jest ustawiony) bÄ dĹş asynchroniczny (reset nastÄpuje gdy tylko sygnaĹ resetu bÄdzie ustawiony, niezaleĹźnie od zegara); domyĹlny (i zalecany) wybĂłr to reset synchroniczny MoĹźemy utworzyÄ nowÄ domenÄ zegarowÄ nastÄpujÄ co:: moja_domena = ClockDomain( # parametry i ich domyĹlne wartoĹci: reset_less=False, # jeĹli True, domena nie bÄdzie miaĹa resetu clk_edge='pos', # wybĂłr aktywnego zbocza zegara â 'pos' oznacza rosnÄ ce, 'neg' oznacza malejÄ ce async_reset=False, # jeĹli True, reset jest asynchroniczny local=False, # jeĹli True, stworzona domena rozpropaguje siÄ tylko do podmoduĹĂłw; jeĹli False, rozpropaguje siÄ po caĹym ukĹadzie ) m.domains += moja_domena # PodĹÄ czamy sygnaĹ zegarowy, taki jak w oryginalnej domenie sync # Zamiast tego moĹźna by np. uĹźyÄ PLL czy BUFGCE do uĹźycia innego zegara. # MoĹźna teĹź nie podĹÄ czaÄ tutaj nic, by zegar domeny byĹ wejĹciem ukĹadu m.d.comb += moja_domena.clk.eq(ClockSignal('sync')) # PodĹÄ czemy reset. m.d.comb += moja_domena.rst.eq(moj_reset) ctr = Signal(4) # To spowoduje wygenerowanie logiki w naszej nowej domenie. m.d.moja_domena += ctr.eq(ctr + 1) Domeny zegarowe automatycznie propagujÄ siÄ w caĹym ukĹadzie â wystarczy jÄ stworzyÄ w jednym module, by byĹa widoczna wszÄdzie (chyba, Ĺźe ustawimy jej parametr local). Czasem chcemy uĹźyÄ moduĹu "przenoszÄ c" go do innej domeny zegarowej â powiedzmy, Ĺźe chcemy uĹźyÄ jakiegoĹ gotowego moduĹu z biblioteki przystosowanego do pracy w domyĹlnej domenie ``sync``, lecz chcemy by dziaĹaĹ w naszej domenie. Do takich zastosowaĹ moĹźemy uĹźyÄ konstrukcji ``DomainRenamer``:: # Domena 'sync' w moj_podmodul i jego podmoduĹach jest tym samym co nasza domena # 'moja_domena' i kompletnie niezaleĹźna od naszej domeny 'sync' m.submodules.moj_podmodul = moj_podmodul = DomainRenamer({'sync': 'moja_domena'})(ModulZBiblioteki(...)) Komunikacja miÄdzy domenami zegarowymi ====================================== MajÄ c w ukĹadzie cyfrowym wiele domen zegarowych musimy w jakiĹ sposĂłb przesyĹaÄ dane miÄdzy tymi domenami. Poziom skomplikowania tego zaleĹźy od tego, jak duĹźo danych mamy do przesĹania, oraz od tego jaka jest wzajemna relacja zegarĂłw w tych domenach. Zdarza siÄ, Ĺźe dwie domeny sÄ synchroniczne wglÄdem siebie i moĹźemy deterministycznie po prostu uĹźywaÄ w jednej domenie sygnaĹĂłw wygenerowanych w drugiej domenie. Dzieje siÄ tak, gdy: - domeny majÄ ten sam zegar (róşniÄ siÄ tylko resetem) - domeny majÄ ten sam sygnaĹ zegarowy, ale przeciwne aktywne zbocza - domeny majÄ róşne sygnaĹy zegarowe, ale pochodzÄ ce z jednego ĹşrĂłdĹa z dobrze zdefiniowanÄ relacjÄ fazy, np. - dwa wyjĹcia PLL o tej samej czÄstotliwoĹci, ale fazie 0° i 90° - dwa wyjĹcia PLL, jedno o czÄstotliwoĹci 100MHz, drugie o czÄstotliwoĹci 200MHz, wyrĂłwnane w fazie (kaĹźde rosnÄ ce zbocze wolnego zegara jest jednoczeĹnie rosnÄ cym zboczem szybkiego zegara) - sygnaĹy zegarowe w obu domenach sÄ zmodyfikowanymi (np. przez ``BUFGCE``) wersjami tego samego sygnaĹu bazowego W przeciwnym wypadku domeny nazywamy asynchronicznymi wzglÄdem siebie i musimy bardzo uwaĹźaÄ w komunikacji miÄdzy nimi, by uniknÄ Ä problemu metastabilnoĹci. W przypadku prostych sygnaĹĂłw (np. linii przerwania) wystarcza synchronizator. Problemy zaczynajÄ siÄ jednak, gdy mamy do przesĹania bardziej skomplikowane dane. Kod Graya --------- ZaĹóşmy, Ĺźe chcemy przekazaÄ miÄdzy dwiema domenami jakÄ Ĺ liczbÄ, ktĂłra moĹźe zmieniÄ siÄ co najwyĹźej o 1 (w gĂłrÄ bÄ dĹş w dĂłĹ) w kolejnych cyklach zegara. Przekazanie jej bezpoĹrednio przez tablicÄ synchronizatorĂłw nie zadziaĹa â przy zmianie liczby, zmiany róşnych bitĂłw mogÄ dojĹc w róşnych cyklach do nowej domeny zegarowej. Istnieje jednak kodowanie liczb, ktĂłre rozwiÄ zuje ten problem â zapewnia, Ĺźe kaĹźde kolejne dwie liczby sÄ kodowane do wektorĂłw bitowych róşniÄ cych siÄ w dokĹadnie jednej pozycji. Jest to kod Graya. Dla przykĹadu, kod 4-bitowy: - 0: 0000 - 1: 0001 - 2: 0011 - 3: 0010 - 4: 0110 - 5: 0111 - 6: 0101 - 7: 0100 - 8: 1100 - 9: 1101 - 10: 1111 - 11: 1110 - 12: 1010 - 13: 1011 - 14: 1001 - 15: 1000 Aby zakodowaÄ liczbÄ ``x`` do kodu graya, wystarczy policzyÄ ``x ^ (x >> 1)``. Dekodowanie jest trochÄ bardziej skomplikowane, ale doĹc efektywnie realizowalne w sprzÄcie. FIFO ---- Do przekazania duĹźej iloĹci danych miÄdzy domenami zegarowymi najczÄĹciej uĹźywa siÄ kolejek FIFO zrealizowanych za pomocÄ blokĂłw RAMu uĹźywanych jako buforĂłw cyklicznych: - jeden port dziaĹa tylko w trybie zapisu w domenie ĹşrĂłdĹowej - drugi port dziaĹa tylko w trybie odczytu w domenie docelowej - wskaĹşniki odczytu i zapisu sÄ przekazywane miÄdzy domenami zegarowymi w kodzie Graya poprzez tablicÄ synchronizatorĂłw