On synchronization methods across clock domains

Guest
Hello! I'm currently designing a largish multi-clock digital core in
Verilog. I have a source clock, srcclk, which can be as slow as 1000
times slower than dstclk, or up to 2x faster than dstclk.

I need to synchronize a control from the srcclk to the dstclk. This
control is assuredly signalled every 8 srcclk cycles (as long as the
part is enabled, anyway). My design for synchronization uses an
either-edge detector, so that I can handle crossing clock domains from
faster to slower or slower to faster, like so:

always @(posedge srcclk, negedge reset_n) if(!reset_n) foo_command <=
0 else begin
if(en && every8thcycle) begin
foo_command <= ~foo_command; end end

two_reg_synchronizer a(
.in(foo_command),
.out(foo_sync),
.clk(dstclk),
.reset_n(reset_n));

always @(posedge dstclk) begin
d_foo_sync <= foo_sync; end
wire foo = (d_foo_sync != foo_sync);

I have a piece of data that is generated every 8 srcclk cycles and the
foo command is intended to tell the destination that the data for that
8-cycle set is ready. Basically, I have no control over srcclk.
dstclk is constant.

My question is, why isn't such a structure recommended by any of the
sites I've seen? Most of them just recommend the sync + rising-edge/
falling-edge detector for slow-to-fast clock domain crossings, or else
the handshaking request-acknowledge (which still uses an edge
detector, but the signal is deasserted only on ackowledgement).

I can't use the plain edge detector (because my source clock can be
faster than the destination clock) and using a handshaking request-
acknowledge won't deassert the signal fast enough for cases when the
source clock reaches 2x my destination clock (the synchronization on
both directions takes too much time).

This is the reason I developed the above synchronization style, but
I'm concerned that no one recommends it (or do I need to improve my
google-trawling skillz?). Is there any particular reason why it
isn't?

Granted, this is a digital design question not specific to Verilog -
should it be asked elsewhere?

Sincerely,
AmkG
 
Is your command multi-bit? What happens when the dstclk samples some
changing bits in one cycle and the rest in the next? If multiple bits
change, you can never guarantee that you'll register all the changing
bits in only one cycle.

A two register synchronizer is great for a single signal but will not
help for multi-bit values.

If your wire foo is used to validate the data is steady for two cycles -
which isn't clear since your two_reg_synchronizer module isn't obvious -
then this technique actually is recommended. You effectively have a
slower domain being sampled by a higher speed domain since your srcclk
signal lasts 8 clocks. The transfer from a slower to faster domain is
often done by verifying the value doesn't change in consecutive cycles;
if the value has changed, all bits may have been sampled or not. If the
sample is consistent, the read value is stable and usable.

- John_H


almkglor@gmail.com wrote:
Hello! I'm currently designing a largish multi-clock digital core in
Verilog. I have a source clock, srcclk, which can be as slow as 1000
times slower than dstclk, or up to 2x faster than dstclk.

I need to synchronize a control from the srcclk to the dstclk. This
control is assuredly signalled every 8 srcclk cycles (as long as the
part is enabled, anyway). My design for synchronization uses an
either-edge detector, so that I can handle crossing clock domains from
faster to slower or slower to faster, like so:

always @(posedge srcclk, negedge reset_n) if(!reset_n) foo_command <=
0 else begin
if(en && every8thcycle) begin
foo_command <= ~foo_command; end end

two_reg_synchronizer a(
.in(foo_command),
.out(foo_sync),
.clk(dstclk),
.reset_n(reset_n));

always @(posedge dstclk) begin
d_foo_sync <= foo_sync; end
wire foo = (d_foo_sync != foo_sync);

I have a piece of data that is generated every 8 srcclk cycles and the
foo command is intended to tell the destination that the data for that
8-cycle set is ready. Basically, I have no control over srcclk.
dstclk is constant.

My question is, why isn't such a structure recommended by any of the
sites I've seen? Most of them just recommend the sync + rising-edge/
falling-edge detector for slow-to-fast clock domain crossings, or else
the handshaking request-acknowledge (which still uses an edge
detector, but the signal is deasserted only on ackowledgement).

I can't use the plain edge detector (because my source clock can be
faster than the destination clock) and using a handshaking request-
acknowledge won't deassert the signal fast enough for cases when the
source clock reaches 2x my destination clock (the synchronization on
both directions takes too much time).

This is the reason I developed the above synchronization style, but
I'm concerned that no one recommends it (or do I need to improve my
google-trawling skillz?). Is there any particular reason why it
isn't?

Granted, this is a digital design question not specific to Verilog -
should it be asked elsewhere?

Sincerely,
AmkG
 
Check out http://www.bawankule.com/verilogcenter/files/10_1.pdf

David Walker

On Mar 20, 6:16 am, John_H <newsgr...@johnhandwork.com> wrote:
Is your command multi-bit? What happens when the dstclk samples some
changing bits in one cycle and the rest in the next? If multiple bits
change, you can never guarantee that you'll register all the changing
bits in only one cycle.

A two register synchronizer is great for a single signal but will not
help for multi-bit values.

If your wire foo is used to validate the data is steady for two cycles -
which isn't clear since your two_reg_synchronizer module isn't obvious -
then this technique actually is recommended. You effectively have a
slower domain being sampled by a higher speed domain since your srcclk
signal lasts 8 clocks. The transfer from a slower to faster domain is
often done by verifying the value doesn't change in consecutive cycles;
if the value has changed, all bits may have been sampled or not. If the
sample is consistent, the read value is stable and usable.

- John_H

almkg...@gmail.com wrote:
Hello! I'm currently designing a largish multi-clock digital core in
Verilog. I have a source clock, srcclk, which can be as slow as 1000
times slower than dstclk, or up to 2x faster than dstclk.

I need to synchronize a control from the srcclk to the dstclk. This
control is assuredly signalled every 8 srcclk cycles (as long as the
part is enabled, anyway). My design for synchronization uses an
either-edge detector, so that I can handle crossing clock domains from
faster to slower or slower to faster, like so:

always @(posedge srcclk, negedge reset_n) if(!reset_n) foo_command <=
0 else begin
if(en && every8thcycle) begin
foo_command <= ~foo_command; end end

two_reg_synchronizer a(
.in(foo_command),
.out(foo_sync),
.clk(dstclk),
.reset_n(reset_n));

always @(posedge dstclk) begin
d_foo_sync <= foo_sync; end
wire foo = (d_foo_sync != foo_sync);

I have a piece of data that is generated every 8 srcclk cycles and the
foo command is intended to tell the destination that the data for that
8-cycle set is ready. Basically, I have no control over srcclk.
dstclk is constant.

My question is, why isn't such a structure recommended by any of the
sites I've seen? Most of them just recommend the sync + rising-edge/
falling-edge detector for slow-to-fast clock domain crossings, or else
the handshaking request-acknowledge (which still uses an edge
detector, but the signal is deasserted only on ackowledgement).

I can't use the plain edge detector (because my source clock can be
faster than the destination clock) and using a handshaking request-
acknowledge won't deassert the signal fast enough for cases when the
source clock reaches 2x my destination clock (the synchronization on
both directions takes too much time).

This is the reason I developed the above synchronization style, but
I'm concerned that no one recommends it (or do I need to improve my
google-trawling skillz?). Is there any particular reason why it
isn't?

Granted, this is a digital design question not specific to Verilog -
should it be asked elsewhere?

Sincerely,
AmkG
 
On Mar 20, 9:16 pm, John_H <newsgr...@johnhandwork.com> wrote:
Is your command multi-bit? What happens when the dstclk samples some
changing bits in one cycle and the rest in the next? If multiple bits
change, you can never guarantee that you'll register all the changing
bits in only one cycle.
Single-bit. I'm using a single-bit command so that the data (which I
assure to be stable until the next assertion of the command) can be
safely multi-bit. Basically, the holding register is changed at the
same time that the single-bit foo_command is changed; I assume with
the delays in the two-register synchronizer that the data will be
stable by the time the dstclk-clocked logic receives the foo_command.
Is this assumption valid?

A two register synchronizer is great for a single signal but will not
help for multi-bit values.
Yep ^^.

Thanks! Hmm, I'd really like to release the code as open source just
so that I can ask if my design is screwy or not, but my boss won't let
me! Erk. I've seen too much proprietary code with questionable
design decisions (one had a FIFO buffer that was implemented as a
double-buffering scheme, meaning I needed to empty the buffer at a
very specific level. My bosses wanted a programmable level trigger
but it was just impossible with that design. Worse, there were two
level registers, one for each end. The two level registers would be
acceptable if both ends were clocked at different clocks, but the
whole FIFO was synchronous. Some nasty bugs involved the two
registers getting out of sync, i.e. having different values.)
 
On Mar 21, 12:14 am, "dbwalker0...@gmail.com" <dbwalker0...@gmail.com>
wrote:
Check outhttp://www.bawankule.com/verilogcenter/files/10_1.pdf

David Walker
Okay... I definitely need to #enhance my google-trawling skills!

Thanks! Nice resource.

AmkG
 

Welcome to EDABoard.com

Sponsor

Back
Top