4
\$\begingroup\$

I am working on my first non-trival FPGA design and finally have a need for Clock Domain Crossing (CDC).

There are multiple resources (amongst others) which discuss various architectures for CDC and some related questions. The theory is fine, but at least one of those resources lists traps for the unwary and at least one project lists multiple VHDL attributes required to synthesize correctly on a Xilinx device.

I am targeting the Altera MAX10 for this project using VHDL. I have hand-coded a push-handshake synchoniser, but I somehow suspect there is more to it.

So:

  • Does Altera (or another well-regarded source) supply a library of synchronisation primitives?
  • If not, what steps need to be taken to ensure that a hand-written synchronisation block synthesises correctly, simulates correctly and is subjected to timing analysis correctly?

An answer with an example of a basic synchroniser (e.g. 2-Flop) would be well regarded.

\$\endgroup\$
  • \$\begingroup\$ What kind of signal do you want to synchronize? A strobe, a flag, a counter value, a bit vector or something more complex? \$\endgroup\$ – Paebbels Aug 11 '15 at 6:25
  • \$\begingroup\$ A std_logic_vetor. I have naievely implented the four-phase handshaking synchroniser from this paper which simulates correctly, but I'm not convinced that I have "told" the FPGA everything it needs to know to synthsize correctly. \$\endgroup\$ – Damien Aug 11 '15 at 6:41
  • 1
    \$\begingroup\$ See this question where an answer lists several altera attributes for synchronisation. \$\endgroup\$ – Damien Aug 13 '15 at 6:48
  • \$\begingroup\$ I updated the synchronizer modules in our PoC-Library and uploaded the first changes to GitHub. Thanks for the link to Altera's attributes.. I'll test it in a Stratix IV design and update my post if everything works as espected. Currently, my design crashes Quartus so it's hard to find the faulty code line (Xilinx compiles my VHDL files without complains). \$\endgroup\$ – Paebbels Aug 14 '15 at 0:54
  • 1
    \$\begingroup\$ Hello again. I updated the PoC sources and my answer to address the Altera specific synchronizers. Currently these circuits work in a StratixIV design on a DE4 board. \$\endgroup\$ – Paebbels Aug 22 '15 at 2:43
7
\$\begingroup\$

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?

  1. 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.
  2. Mark the registers as asynchronous registers (ASYNC_REG = TRUE). This is needed for post-synthesis simulations to suppress meta stable values.
  3. Place registers near each other (RLOC = X0Y0). This places the 2-FF synchronizer into the same slice.
  4. 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?

  1. Both flip flops are marked with PRESERVE to hinder optimizations.
  2. 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.

  3. 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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.