The presented four-phase synchronizer is a good and correct implementation.
It has only one disadvantage:
It has a V
input, to notify the synchronizer of changed inputs.
This can be automated by a n-bit register in the source clock domain and n-bit comparator: if input changed, assert V=1
.
Input_d <= Input when rising_edge(Clock);
V <= '1' when (Input_d /= Input) else '0'; -- input changed
Implementation of a 2-FF synchronizer - the core of every higher level synchronizer - with the required attributes and constraints may be found as follows:
What's so special compared to normal double flip flops?
- It disables shift register extraction (
SHREG_EXTRACT = NO
). Synthesis tries to find chains of flip flops and put them into dedicated shift registers like Xilinx SRL32
. These dedicated shifters are not good for meta stable inputs.
- Mark the registers as asynchronous registers (
ASYNC_REG = TRUE
). This is needed for post-synthesis simulations to suppress meta stable values.
- Place registers near each other (
RLOC = X0Y0
). This places the 2-FF synchronizer into the same slice.
The flip flops have unique names and are put into a special timing group called METASTABILITY_FFS
. Xilinx constraints:
INST "*FF1_METASTABILITY_FFS" TNM = "METASTABILITY_FFS";
All timing paths from a normal FF to a metastable FF are ignored, via the TIG
constraint.
NET "*_async" TIG;
INST "*_meta*" TNM = "METASTABILITY_FFS";
TIMESPEC "TS_MetaStability" = FROM FFS TO "METASTABILITY_FFS" TIG;
Sources: sync_Bits_Xilinx.ucf, Metastability.ucf
Edit: Altera specific 2-FF synchronizer:
I added a new generate statement into the generic 2-FF implementation, to choose an Altera specific implementation: sync_Bits_Altera.vhdl
Whats so special about this version?
- Both flip flops are marked with
PRESERVE
to hinder optimizations.
The first / the meta stable flip flop is annotated with:
attribute ALTERA_ATTRIBUTE of Data_meta : signal is "-name SYNCHRONIZER_IDENTIFICATION ""FORCED IF ASYNCHRONOUS""";
to mark this flip flops as a synchronizer circuit.
All paths to these registers are set as a false_path
:
attribute ALTERA_ATTRIBUTE of rtl : architecture is "-name SDC_STATEMENT ""set_false_path -to [get_registers {*|sync_Bits_Altera:*|\gen:*:Data_meta}] """;
This is the inline SDC constraint annotation syntax.
Higher level synchronizers:
Of cause, the PoC-Library has also a predefined synchronizer for bit vectors called PoC.misc.sync.Vector, which is based on the generic 2-FF synchronizer. If the master bits change, all bits are transferred to the receiver clock domain.