A resposta simples é que eles não fazem por conta própria. O sincronizador não existe para garantir que os dados sejam transmitidos, mas para garantir que você não termine com sinais metaestáveis alimentando muitos outros sinais e causando problemas. O segundo FF, como mostra o diagrama, captura a primeira saída FF metaestável e evita que ela se propague mais através do design.
Existem vários tipos de sinais, e como você inclui sincronizadores depende de qual sinal você está falando. Mas vamos ver alguns tipos comuns:
Sinais de acionamento - ou qualquer sinal que seja basicamente um pulso que deve iniciar outra coisa em execução. Eles geralmente não carregam dados, e tudo o que você está interessado é que haja, digamos, uma vantagem crescente para iniciar algo acontecendo em outro domínio do relógio. Para fazer o cruzamento, você precisaria de um sincronizador (essencialmente fazendo o que é mostrado em seu diagrama), mas precisará de um pouco mais.
A opção mais simples é estender o pulso - essencialmente, você deve garantir que o pulso de entrada tenha mais de 1 período de relógio do relógio de destino (deve ser maior que 1 ciclo, pelo menos, o maior tempo de configuração e espera do registro de destino) . Por exemplo, se você estiver passando de um relógio de 20 MHz para um relógio de 15 MHz, verifique se o pulso tem dois ciclos de relógio na entrada, o que garantiria que ele seja apresentado ao relógio de destino e não seja perdido. Isso também responde à sua pergunta sobre como o sinal é garantido. Se o pulso for maior que um período do relógio de destino, significa que, se for metaestável no primeiro limite do relógio e acabar sendo visto como 0, então no segundo limite do relógio, ele definitivamente capturará o pulso.
Como com esse tipo de sinal, você só está interessado em que o pulso tenha passado, não importa se o sinal de saída termina com dois ciclos de clock altos algumas vezes e apenas um ciclo do resto. Se você precisar garantir que seja um pulso de ciclo único, instale um circuito simples de detecção de borda.
Barramentos de controle - ou possivelmente tipos de barramentos de dados. Estes são sem dúvida mais difíceis, porque se você tiver um fluxo de dados de vários bits, ele precisará permanecer sincronizado. Nesse caso, o que você faria é implementar algo chamado "handshaking". Você basicamente carrega seus dados no relógio de origem e os segura. Em seguida, você envia um sinal de solicitação (como em 1) através de um sincronizador. Depois que o sinal de solicitação é transmitido, você sabe que o barramento de dados também será estabilizado no domínio de destino. Você pode cronometrar em um banco de registro no destino. O destino envia novamente um pulso de confirmação para informar a fonte de que pode carregar a próxima palavra.
Você usaria esse tipo de barramento se precisasse enviar uma palavra de controle para o relógio de destino, para o qual precisa saber que ela chegou antes de enviar outra (por exemplo, se você estiver enviando um comando para fazer alguma coisa).
Barramentos de dados - para dados em que você tem uma fonte que divulga dados continuamente ou em rajadas, é melhor usar um FIFO do que sincronizadores. O FIFO usa uma memória de relógio duplo para armazenar os dados, juntamente com contadores para acompanhar a quantidade de dados no FIFO. Você grava os dados no FIFO quando há espaço e depois incrementa o endereço de gravação. Esse endereço é tipicamente codificado em um esquema "Gray Coding", que garante que cada incremento no endereço cause apenas umbit no barramento de endereços para mudar (o que significa que você não precisa sincronizar vários bits). Esse endereço é então transferido para o domínio de destino (através de uma de suas cadeias sincronizadoras), onde é comparado com o endereço de leitura. Se houver dados no FIFO, eles poderão ser lidos na memória usando a porta do relógio de destino. O endereço de leitura também é codificado em cinza e enviado de volta à fonte através de outro sincronizador, para que a porta de gravação possa calcular se há algum espaço no FIFO.
Redefinir sinais - normalmente, eles usam uma versão modificada do sincronizador no que é conhecido como "Assíncrona assertiva, desativada síncrona". Nesta versão modificada, a entrada de dados para o primeiro flip-flop é vinculada ao GND e, em vez disso, o sinal de redefinição de entrada é conectado aos sinais predefinidos assíncronos de cada flip-flop no sincronizador. Isso resulta em um sinal de saída que é totalmente assíncrono quando aumenta, mas a cadeia do sincronizador garante que diminua de forma síncrona com o relógio de destino, marcando zeros na cadeia de registro.
Esse tipo de sincronizador é terrível para dados e controle, mas perfeitamente adequado para redefinir sinais. Se toda a lógica de destino alimentar a saída dessa cadeia nas entradas de redefinição assíncrona de qualquer registro no domínio, haverá pouca preocupação com a metastabilidade na declaração (mesmo que seja assíncrona), pois todos os registros são forçados a um estado conhecido. Então, quando o sinal de redefinição é desativado no domínio de origem, ele é desativado de forma síncrona no domínio de destino, o que significa que todos os registros saem da redefinição no mesmo ciclo de clock (em vez de +/- 1 ciclo, se foi desativado de forma assíncrona).
Como você pode ver acima, é muito mais complexo fazer uma travessia no domínio do relógio do que simplesmente colocar um sincronizador de 2 flip-flop no sinal. O método exato usado depende da aplicação.