Design practice crossing clock domains and async signals
Today even FPGA designs can have extremely complex clocking architectures and many async inputs, resulting in many potential CDC issues.

I'd say that the following points constitute a minimal set of "rules of thumb" for avoiding CDC bugs:


Keep track of all signals which cross clock domains (diagrams, lists, spreadsheets - whatever you find more convenient). Async input signals should be included too.
All signals from the above list must be synchronized, unless there is a clear reason why not.
Never ever synchronize multi-bit signals bit-by-bit! Use special synchronization schemes for buses instead (sync FIFO, two way handshake, etc.).
If there is an async reset in the system, and this reset does not apply to all the flip-flops - all the signals originating in this reset domain and passed to non-reset logic should be treated as async (and included in the list from #1)


I'm sure that the above list of practices is incomplete, and can be easily extended.

I also suggest considering CDC verification tools (like Questa CDC from Mentor) - these tools use formal techniques to automatically detect CDC issues in your design.