1
\$\begingroup\$

I know that asynchronous FIFO and handshake can do CDC, but the FIFO consume more resource, and handshake is a little complicated. If I have a multi bit signal "src", and it vary slowly, I want to synchronize it to "dst_clk" as "dst", can I simply sample it like this?

always @(posedge dst_clk) dst0 <= src; always @(posedge dst_clk) dst1 <= dst0; always @(posedge dst_clk) dst2 <= dst1; always @(posedge dst_clk) if (dst1 == dst2) dst <= dst2; 

I think dst0 and dst1 can eliminate metastability, and dst2 validate the new value is correct, is my idea correct? And if I need to set_max_delay between src and dst0?

\$\endgroup\$
5
  • \$\begingroup\$ How often does the src change? \$\endgroup\$ Commented Aug 29 at 14:14
  • \$\begingroup\$ Your code is identical to how you would implement a one-way handshake (without feedback from dst to src) - but done in a more complicated way. It's sufficient to put just 1 bit through the chain of flipflops and leave the data just untouched. \$\endgroup\$ Commented Aug 29 at 14:15
  • \$\begingroup\$ What is CDC. I have heard of CRC and not CDC \$\endgroup\$ Commented Oct 23 at 20:05
  • 2
    \$\begingroup\$ @SnappyRiffs: This question has the cdc tag, which has a tag description. It's "Clock Domain Crossing" \$\endgroup\$ Commented Oct 23 at 21:20
  • \$\begingroup\$ I realized that after looking at the tag :) \$\endgroup\$ Commented Oct 24 at 22:31

1 Answer 1

1
\$\begingroup\$

That's one way to do it, but it uses three FFs for every bit of data.

A more efficient way would be to use a single FF for each data bit, but pass a "strobe" pulse through a synchronizer to update the register. If the source already has a strobe pulse when it updates, so much the better, but even if it doesn't, you can do change detection on the source side to create such a pulse.

// Optional change detector always @(posedge src_clk) begin if (src <> src1) toggle <= !toggle; src1 <= src; end // Otherwise, just do the toggle based on the existing source strobe pulse. always @(posedge src_clk) if (strobe) toggle <= !toggle; // In either case, update the output once the toggle edge passes through a synchronizer. always @(posedge dst_clk) begin toggle1 <= toggle; toggle2 <= toggle1; toggle3 <= toggle2; if (toggle3 ^ toggle2) dst <= src; end 
\$\endgroup\$
5
  • \$\begingroup\$ Thanks, I get this way can save FFs, and I have a doubt if the toggle need a reset in first method . And in my design, due to some reasons, I obtain "src_clk" a bit difficult. Are there other methods to synchronize "src" without "src_clk"? \$\endgroup\$ Commented Aug 30 at 15:28
  • 1
    \$\begingroup\$ No, not really. If you don't have access to the source clock, you have to treat all of the data bits as individually asynchronous, and therefore your original approach is probably most appropriate. At this point, it isn't really a clock domain crossing as we normally think of it. \$\endgroup\$ Commented Aug 31 at 1:09
  • \$\begingroup\$ And yes, the toggle signal does require initialization for simulation, but in the physical implementation, it really doesn't matter how it starts up. \$\endgroup\$ Commented Aug 31 at 1:14
  • \$\begingroup\$ In my original approach, is it necessary to constraint the path between "src" and “dst0" like the constraint of gray code? \$\endgroup\$ Commented Aug 31 at 3:36
  • \$\begingroup\$ I don't know what you mean by "the constraint of gray code". \$\endgroup\$ Commented Aug 31 at 11:02

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.