The biggest problem with getting data between clock domains is metastability. Metastability can occur where you try to latch a signal at time when that signal is in transition. What we need is a reliable means to ensure that one register's Q's are going to meet the setup and hold time for another register's D's. To do this, we store data (the payload) in a register in one clock domain and make sure we hold it there unchanged long enough to ensure that we can reliably store it into a register in the other domain. To ensure that payload data is held long enough, we handshake between the two clock domains by, essentially, passing a token back and forth, and when metastability affects the token, the worst case is a slight additional delay in passing the payload.
Here's a circuit diagram: http://opengraphics.gitk.com/sync.gif And here's the source code: module sync( in_clock, in_data, out_reset, out_clock, out_data); parameter HIGHBIT = 7; input out_reset; input in_clock, out_clock; input [HIGHBIT:0] in_data; output [HIGHBIT:0] out_data; reg flag_1, flag_2, flag_3, flag_4, flag_5; reg [HIGHBIT:0] data_hold, out_data; always @(negedge in_clock) flag_1 <= !flag_5; always @(posedge in_clock) begin if (!flag_2) data_hold <= in_data; flag_2 <= flag_1; end always @(negedge out_clock) begin if (out_reset) begin flag_4 <= 0; end else begin flag_4 <= flag_3; end end always @(posedge out_clock) begin if (out_reset) begin flag_3 <= 0; flag_5 <= 1; out_data <= 0; end else begin flag_3 <= flag_2; flag_5 <= flag_4; if (flag_4 & !flag_5) out_data <= data_hold; end end endmodule Note that the placement of the inverter is somewhat arbitrary. Since inverters are usually free, we can do this. If the inverter were a separate component, it would be better to put it between registers of the same clock domain. _______________________________________________ Open-graphics mailing list [email protected] http://lists.duskglow.com/mailman/listinfo/open-graphics List service provided by Duskglow Consulting, LLC (www.duskglow.com)
