Простой ответ заключается в том, что они не самостоятельно. Синхронизатор предназначен не для того, чтобы гарантировать передачу данных, а для того, чтобы вы не получали метастабильные сигналы, которые подают множество других сигналов и вызывают проблемы. Второй FF, как показано на диаграмме, улавливает первый метастабильный выход FF и предотвращает его дальнейшее распространение в проекте.
Существуют различные виды сигналов, и то, как вы включите синхронизаторы, зависит от того, о каком сигнале вы говорите. Но давайте рассмотрим пару общих типов:
Сигналы запуска - или любой сигнал, который в основном является импульсом, который должен запустить что-то еще. Как правило, они не несут данных, и все, что вас интересует, - это, скажем, повышение, чтобы начать что-то происходить в другом домене часов. Чтобы их пересечь, вам понадобится синхронизатор (по сути, делающий то, что показано на диаграмме), но вам нужно немного больше.
Самый простой вариант - продлить импульс - по сути, вы должны убедиться, что входной импульс длится более 1 такта от тактов назначения (он должен быть длиннее 1 такта как минимум на большее время установки и удержания для регистра назначения) , Например, если вы переходите от тактовой частоты 20 МГц к тактовой частоте 15 МГц, вы должны убедиться, что ваш импульс имеет два тактовых импульса на входе, что обеспечит его передачу на тактовый генератор назначения и не будет потеряно. Это также отвечает на ваш вопрос о том, как сигнал будет проходить гарантированно. Если импульс шире, чем один тактовый период назначения, это означает, что если он становится метастабильным на первом фронте тактового сигнала и в конечном итоге воспринимается как 0, то на втором фронте тактового импульса он определенно поймает импульс.
Поскольку с этим типом сигнала вас интересует только то, что импульс прошел, не имеет значения, заканчивается ли выходной сигнал двумя тактовыми циклами в течение некоторого времени и только одним циклом в остальном. Если вам необходимо убедиться, что это импульс с одним циклом, вы можете создать простую схему детектора контуров.
Шины управления - или, возможно, типы шин данных. Это, возможно, более сложно, потому что, если у вас есть многоразрядный поток данных, который должен оставаться синхронизированным. В этом случае вы должны реализовать то, что называется «рукопожатие». Вы в основном загружаете свои данные на исходные часы и удерживаете их. Затем вы отправляете сигнал запроса (как в 1) через синхронизатор. Когда сигнал запроса пройден, вы знаете, что шина данных также стабилизируется в домене назначения. Затем вы можете отправить его в реестр банка в пункте назначения. Затем пункт назначения снова отправляет импульс подтверждения, чтобы сообщить источнику, что он может загрузить следующее слово.
Вы бы использовали этот тип шины, если вам нужно было отправить управляющее слово на часы назначения, для которых вам нужно знать, что оно было получено перед отправкой другого (например, если вы отправляете команду что-то сделать).
Шины данных - для данных, где у вас есть источник, который выплевывает данные непрерывно или в пакетном режиме, вам, вероятно, лучше использовать FIFO, чем синхронизаторы. FIFO использует двухчасовую память для хранения данных, а также счетчики для отслеживания объема данных в FIFO. Вы записываете данные в FIFO при наличии свободного места, а затем увеличиваете адрес записи. Затем этот адрес обычно кодируется в схеме «серого кодирования», которая гарантирует, что каждое увеличение адреса вызывает только одинбит в адресной шине для изменения (это означает, что вам не нужно синхронизировать несколько битов). Этот адрес затем передается в домен назначения (через одну из цепочек синхронизатора), где он сравнивается с адресом чтения. Если в FIFO есть данные, они могут быть считаны из памяти с помощью порта часов назначения. Адрес чтения аналогично кодируется Греем и отправляется обратно источнику через другой синхронизатор, чтобы порт записи мог вычислить, есть ли место в FIFO.
Сигналы сброса - обычно они используют модифицированную версию синхронизатора, известную как «асинхронное утверждение, синхронная пустыня». В этой модифицированной версии ввод данных в первый триггер привязан к GND, и вместо этого входящий сигнал сброса подключается к асинхронным предустановленным сигналам каждого триггера в синхронизаторе. Это приводит к выходному сигналу, который является полностью асинхронным, когда он достигает высокого уровня, но цепочка синхронизатора гарантирует, что он понижается синхронно с тактовыми импульсами назначения, синхронизируя нули в цепочке регистров.
Этот тип синхронизатора ужасен для данных и управления, но идеально подходит для сброса сигналов. Если вся логика назначения подает выходные данные этой цепочки на входы асинхронного сброса любого регистра в домене, то мало беспокоится о метастабильности при утверждении (даже если она асинхронная), поскольку все регистры переводятся в известное состояние. Затем, когда сигнал сброса сбрасывается в исходном домене, он синхронно сбрасывается в домене назначения, что означает, что все регистры выходят из сброса за один и тот же тактовый цикл (а не цикл +/- 1, если он был асинхронным деактивированием).
Как вы можете видеть из вышеизложенного, гораздо сложнее выполнить пересечение часового домена, чем просто прикрепить синхронизатор с двумя триггерами к сигналу. Точный метод зависит от приложения.