Clock Synchronization

By: Colin Durocher, Jeffrey Spiers, Angela Wong, Richard Mao

Last Modified on March 29, 2001


Introduction

This document explains a scheme to deal with synchronizing two clock domains, both running at the same frequency but with an unknown phase relation.  This problem occurs when implementing an ethernet controller to conform to the IEEE 802.3u standard interface (MII).  An MII interface provides two clocks to the controller.  The transceiver has an rx_clk output, on the rising edge of which it expects you to read a 4-bit data nibble, and a tx_clk output, on the rising edge of which it expects a data nibble to be ready for it to read.  Both of these clocks run at 2.5 or 25 MHz, depending on whether the ethernet is running at 10 Mb/s or 100 Mb/s.

Problem

We are given two clock domains, clock1 and clock2, of equal frequency and unknown phase.  Data is made available synchronous to clock1 and we want to provide it to a circuit synchronous to clock2.  The two circuits cannot be directly interfaced because the data might be in transition while the system sensitive to clock2 attempts to read it.  In other words, we must avoid reading from a register while it's values are unstable.  Take for example the following:
 

data1:    ----------xx__________________xx-----------------
clock1:   _________----------__________----------__________
clock2:   --_________----------__________----------________
 

In this example, the data is read from the data1 register on clock2 while it is in transition, as denoted by the 'x' characters on the diagram.

Solution

The general idea is to use a faster clock, called sync_clk, that helps to identify when it is safe to read data1.  A clock running at 10 x clock1 will be chosen for sync_clk.  The synchronization hardware is clocked on sync_clk.  The inputs to the synchronization process are clock1, clock2, and data1.

The synchronization hardware consists of a simple state machine and a data register (regA) available to the clock2 domain.  The state machine has the following states: got1_clock1, got1_clock2, stall, update.

The system starts in the update state.  When a '1' is detected on clock1, we enter the got1_clock1 state.  At this point, we know that data1 has been updated and is possibly still in transition.  The system then looks for a '1' on clock2 and enters the got1_clock2 state.  At this point, we know that the circuit in the clock2 domain has read the old value held in regA.  The system then waits for one clock cycle (stall state) and updates regA with the new value of data1 on the next clock cycle (update state). The 1 clock cycle stall is inserted to give data1 time to transition and to respect the hold time of any register in the clock2 domain that regA is being copied into.  The new value of regA will be used by the clock2 circuit on the next rising edge of clock2 at least 1/4 clock2 cycles away.

Assuming that the relative speeds of clock1=clock2 and sync_clk are correct, this scheme guarantees that data1 will not be read until its transition is complete.  It also guarantees that regA will be stable when the clock2 circuit reads from it.  Sync_clk must be chosen such that:

2 x (sync_clk period) < 1/2 x clock1 period
3 x (sync_clk period) > transition time of data1


The following vhdl file is an example of clock synchronization.  It was used to synchronize 5 bits of data between two 2.5 MHz clock domains, using a synchronization clock of 25 MHz.

 sub_sync.vhd