Prosta odpowiedź jest taka, że nie są sami. Synchronizator nie zapewnia transferu danych, ale zapewnia, że nie dostaniesz metastabilnych sygnałów zasilających wiele innych sygnałów i powodujących problemy. Drugi FF, jak pokazuje schemat, łapie metastabilne pierwsze wyjście FF i zapobiega dalszemu rozprzestrzenianiu się przez projekt.
Istnieją różne rodzaje sygnałów, a sposób uwzględnienia synchronizatorów zależy od sygnału, o którym mówisz. Ale spójrzmy na kilka typowych typów:
Sygnały wyzwalające - lub jakikolwiek sygnał będący w zasadzie impulsem, który musi uruchomić coś innego. Na ogół nie niosą żadnych danych, a jedyne, co cię interesuje, to, powiedzmy, rosnąca przewaga, aby rozpocząć coś w innej dziedzinie zegara. Aby je połączyć, potrzebujesz synchronizatora (zasadniczo wykonującego to, co pokazano na schemacie), ale potrzebujesz trochę więcej.
Najprostszą opcją jest przedłużenie impulsu - zasadniczo upewniasz się, że impuls wejściowy jest dłuższy niż 1 okres zegara docelowego zegara (powinien on być dłuższy niż 1 cykl co najmniej większy z czasów ustawiania i utrzymywania rejestru docelowego) . Na przykład, jeśli przechodzisz z zegara 20 MHz na zegar 15 MHz, upewnij się, że twój puls ma dwa cykle zegarowe na wejściu, co zapewni, że zostanie on przedstawiony zegarowi docelowemu i nie zostanie utracony. To również odpowiada na twoje pytanie, w jaki sposób gwarantuje się przejście sygnału. Jeśli puls jest szerszy niż jeden docelowy okres zegara, oznacza to, że jeśli będzie on metastabilny na pierwszej krawędzi zegara i ostatecznie zostanie wyświetlony jako 0, to na drugiej krawędzi zegara na pewno złapie puls.
Ponieważ przy tym typie sygnału interesuje Cię tylko to, że impuls przeszedł, nie ma znaczenia, czy sygnał wyjściowy kończy się dwoma cyklami taktowania przez większość czasu, a tylko jednym cyklem przez resztę. Jeśli chcesz upewnić się, że jest to impuls o jednym cyklu, możesz utworzyć prosty obwód detektora krawędzi.
Kontrolne magistrale - lub ewentualnie typy magistral danych. Są one prawdopodobnie trudniejsze, ponieważ w przypadku wielobitowego strumienia danych, który musi być zsynchronizowany. W tym przypadku powinieneś zaimplementować coś, co nazywa się „handshaking”. Zasadniczo ładujesz swoje dane do zegara źródłowego i trzymasz je. Następnie wysyłasz sygnał żądania (jak w 1) poprzez synchronizator. Gdy sygnał żądania zostanie przesłany, wiesz, że szyna danych zostanie również ustabilizowana w domenie docelowej. Następnie możesz ustawić zegar w banku rejestru w miejscu docelowym. Odbiorca następnie ponownie wysyła impuls potwierdzający, aby poinformować źródło, że może załadować następne słowo.
Użyłbyś tego rodzaju magistrali, gdybyś musiał wysłać słowo kontrolne do zegara docelowego, dla którego musisz wiedzieć, że dotarł tam przed wysłaniem innego (np. Jeśli wysyłasz polecenie, aby coś zrobić).
Magistrale danych - w przypadku danych, w których masz źródło, które wyrzuca dane w sposób ciągły lub seryjny, prawdopodobnie lepiej jest używać FIFO niż synchronizatorów. FIFO wykorzystuje pamięć z dwoma zegarami do przechowywania danych, a także liczniki do śledzenia ilości danych w FIFO. Zapisujesz dane w FIFO, gdy jest miejsce, a następnie zwiększasz adres zapisu. Adres ten jest zwykle kodowany w schemacie „Gray Coding”, który zapewnia, że każdy przyrost adresu powoduje tylko jedenbit w magistrali adresowej, aby zmienić (co oznacza, że nie trzeba synchronizować wielu bitów). Adres ten jest następnie przenoszony do domeny docelowej (przez jeden z łańcuchów synchronizatora), gdzie jest porównywany z adresem odczytu. Jeśli w FIFO znajdują się dane, można je odczytać z pamięci za pomocą docelowego portu zegara. Adres odczytu jest podobnie kodowany w kolorze szarym i wysyłany z powrotem do źródła przez inny synchronizator, aby port zapisu mógł obliczyć, czy w FIFO jest miejsce.
Resetuj sygnały - zwykle używają zmodyfikowanej wersji synchronizatora, znanej jako „Asynchronous Assert, Synchronous Deassert”. W tej zmodyfikowanej wersji dane wprowadzane do pierwszego przerzutnika są powiązane z GND, a zamiast tego przychodzący sygnał resetowania jest połączony z asynchronicznymi wstępnie ustawionymi sygnałami każdego przerzutnika w synchronizatorze. Powoduje to, że sygnał wyjściowy jest całkowicie asynchroniczny, gdy osiąga stan wysoki, ale łańcuch synchronizatora zapewnia, że przechodzi on nisko synchronicznie z zegarem docelowym, taktując przez zera w łańcuchu rejestrów.
Ten typ synchronizatora jest straszny dla danych i kontroli, ale doskonale nadaje się do resetowania sygnałów. Jeśli cała logika docelowa przekazuje dane wyjściowe tego łańcucha do asynchronicznego resetu danych wejściowych dowolnego rejestru w domenie, wówczas nie ma obaw o metastabilność podczas potwierdzenia (nawet jeśli jest ona asynchroniczna), ponieważ wszystkie rejestry są zmuszone do znanego stanu. Następnie, gdy sygnał resetowania jest dezasserowany w domenie źródłowej, synchronicznie deasseruje się w domenie docelowej, co oznacza, że wszystkie rejestry wychodzą z resetowania w tym samym cyklu zegarowym (zamiast cyklu +/- 1, jeśli był to asynchroniczny deassert).
Jak widać z powyższego, przejście o domenę zegarową jest o wiele bardziej skomplikowane niż po prostu naklejenie synchronizatora 2 przerzutów na sygnał. Dokładna zastosowana metoda zależy od zastosowania.