Sign in

username:

password:



Not a member?

Search Comp.Arch.FPGA



Search tips

fpga by Keywords

Altera | ASIC | CPLD | Cyclone | DCM | DDR | DSP | Ethernet | ISE | JTAG | Linux | LVDS | Microblaze | ML310 | Modelsim | NIOS | OPB | PCI | Quartus | RocketIO | SDRAM | Spartan | Spartan3 | SRAM | Stratix | Verilog | VHDL | Virtex | Virtex-4 | Virtex-II | Xilinx | XST

Ads

See Also

DSPEmbedded SystemsElectronics

Comp.Arch.FPGA | Databus crossing clock domains with data freeze

There are 17 messages in this thread.

You are currently looking at messages 10 to 17.

Re: Databus crossing clock domains with data freeze - Nicholas Kinar - 2010-01-06 22:51:00

> 
> I think that I understand how to do this.  The state of the single bit 
> (say data[0] in a 108-bit data word) is examined for a change in the 
> slow clock domain.  If the bit changes, then it is time to read the 
> data.  The 108-bit register is simply copied into another register that 
> is in the slow clock domain.
> 

Whoops, I think that I mean 109-bit data word here, since [108:1] would 
be the data, and data[0] would be the flag bit.  Any other combination 
of data and flag bits also be possible.

My apologies.

Alternately, data[108] could be the flag bit, and [107:0] would then be 
the data.  The possibilities are endless, but it is probably best to 
assign the MSB or the LSB as the flag bit - for the sake of simplicity.



Re: Databus crossing clock domains with data freeze - Jonathan Bromley - 2010-01-07 04:09:00

This really belongs on comp.lang.verilog, but the
topic 
has been flogged to death there; and Verilog users on 
comp.arch.fpga may find it vaguely relevant.

On Wed, 06 Jan 2010 21:04:28 -0600, Nicholas Kinar wrote:

>> What I don't understand is the assignment logic at the top of this 
>> always block.  Isn't "old_slow_flag" equal to
"resync_slow_flag"?

No, it's not.  I carefully and correctly used a nonblocking
assignment <=, causing a delayed update of the target.
Whatever else you do, please get a robust understanding
of the relationship between blocking = and nonblocking <=
assignment before you do anything further with Verilog.
 
>To help me better understand this, I've re-written the code:
>
>reg old_slow_flag;
>reg slow_flag;
>
>always @(posedge fast_clock) begin
>
>     if (old_slow_flag != slow_flag) begin
>
>       old_slow_flag <= slow_flag;
>       freeze_register <= source_data;
>
>       // Do whatever it takes to indicate that
>       // source_data has been consumed, and make
>       // the next source_data available no more
>       // than 2 fast clocks later
>
>     end
>   end

OK, I see what you're saying, but I'm afraid it's 
completely wrong.  I'm not quite sure how to respond
to this, but as a first try I'll explain why your
code is broken and then show you a slightly different
(and perhaps clearer) way to organize the design I 
first offered.

Error #1: Your model will never start running in
simulation, because both regs initialize to 1'bX
(as do all regs in Verilog) and the comparison
   (old_slow_flag != slow_flag)
evaluates to "unknown", because both sides of the
equality are unknown.  When if() tests an unknown
condition, it (by definition) takes the "else"
branch; your code has no "else", so the if() 
statement will do nothing.  Consequently the regs
will remain stuck at X in simulation.  By contrast,
synthesis can't handle X values and will give you
the logic you expect; but that's probably wrong
too, because....

Error #2: slow_flag is generated in the source
clock domain, and therefore may not have enough
setup and hold time relative to the target clock.
Consequently you could get an input hazard:
the comparator result (old != new), which is used
to enable various flipflops, might be detected
"true" by some of the flops and "false" by others.
That's why I took care to resynchronize it.

Subsequently you said that the fast clock is known
to be exactly 4x the slow clock; indeed, with a PLL,
you can get the slow clock's edges exactly lined up
with the fast clock's and you don't need to worry 
about clock domain crossing at all.  That somewhat
changes the goalposts, but my original solution 
remains valid even when the two clocks are completely
asynchronous.

OK< so now let's go back to my example and see 
(a) why it's right and (b) how I could recode it
to be a little easier to follow.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
THIS IS THE BIT THAT YOU REALLY MUST UNDERSTAND.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  always @(posedge fast_clock) begin   // line 1
    resync_slow_flag <= slow_flag;     // line 2
    old_slow_flag <= resync_slow_flag; // line 3
    if (old_slow_flag != resync_slow_flag) begin // 4
      freeze_register <= source_data;
      // Do other related things
    end
  end

On line 1, the always block waits for the next clock 
edge.  So far, so good.
On line 2, we copy the asynchronous signal "slow_flag"
into its resynchronizing register.  However, we use <= 
nonblocking assignment, which means that the updating of
resync_slow_flag is postponed until all other activity
caused by the clock edge has finished.  This postponed
signal update behaviour nicely models the clock-to-output
delay of real flip-flops.  In particular, it means that...
On line 3, we copy resync_slow_flag to old_slow_flag.
But the value of resync_slow_flag that we copy HAS NOT YET
BEEN UPDATED by the nonblocking assignment.  In other
words, we get the flipflop's value as it was just before
the clock edge.  Similarly, on line 4 the values tested
by the if() expression are the values as they were just
before the clock edge.  The same would be true if those
values were tested in any other always block triggered by
the same clock event; the value that you read is the value
as it was just before (and also at the moment of) the clock 
edge.  New values assigned using <= are projected future 
values; they will take effect just after the clock edge 
and, in particular, AFTER the execution of any always
block that was triggered by the same clock.  This is 
precisely how you get proper synchronous behaviour in
Verilog RTL code.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

However, some folk (particularly those coming from a
software background, where assignments always update 
their targets immediately) find this sort of thing a little
awkward to read.  So you can, if you wish, re-code the
always block in a more software-like style provided you
give it some local variables.

  always @(posedge fast_clock) begin : my_resync // 1
    reg resync_slow_flag, old_slow_flag;         // 2
    if (old_slow_flag != resync_slow_flag) begin // 3
      freeze_register <= source_data;            // 4
      // Do other related things                 // 5
    end                                          // 6
    old_slow_flag = resync_slow_flag;            // 7
    resync_slow_flag = slow_flag;                // 8
  end

By labelling the "begin" on line 1, we are entitled to
declare local variables in the block (line 2).  Note that
these variables are STATIC; they are NOT re-initialized
each time the block executes, but instead they hold their
value from its previous execution.
On line 3 we test those variables' values; of course, the
values we get are the values left over from the previous
clock - that's flipflop behaviour.
On lines 7 and 8 we update the variables using blocking
assignment, which takes effect immediately.  Consequently
we must respect your original concerns, and reverse the
order of the two assignments so that the updating of
old_slow_flag uses the old, rather than the updated, value
of resync_slow_flag.

This use of local variables has a number of benefits.  We
have hidden the variables resync_* and old_* inside the
begin...end block where they're used, and they are not
(easily) accessible by other code that shouldn't be 
concerned with them.  We go back to a software-like model
of execution in which local variables update instantly.
However, we MUST continue to use nonblocking assignment
to freeze_reg because it will be read by other blocks
of code, outside this particular always block.  Whenever
you write to a variable within a clocked process, and that
variable will be read by any other process, it's essential
to use nonblocking assignment in this way or else you will
get catastrophic race conditions in simulation, and mismatch
between simulation and synthesis behaviour.

Asks with trepidation..... where did you learn your Verilog,
without finding out about the correct usage of <= ???
-- 
Jonathan Bromley

Re: Databus crossing clock domains with data freeze - Jonathan Bromley - 2010-01-07 04:15:00

On Wed, 06 Jan 2010 15:30:34 -0600, Nicholas
Kinar wrote:

>> Create a divide-by-2 signal in the target domain.  No
>> reset is required, because the phase of the divide-by-2
>> is irrelevant; only its changes are of interest.  So
>> we use a Verilog model that doesn't need a reset in 
>> simulation either:
>> 
>>   always @(posedge slow_clock)
>>     if (slow_flag == 1'b1)
>>       slow_flag <= 0;
>>     else
>>       slow_flag <= 1;
>> 
>
>I see - all that is being done here is a simple clock divisor.  Perhaps 
>this could also be done with a shift register?

I'm not quite sure what you mean here.  In principle, the simplest
possible clock divisor is

  always @(posedge clock)
    clock_2 <= ~clock_2;

It is indeed a shift register; on each clock it shifts
the inverse of itself into itself, and it has only 1 stage.

But this doesn't work in simulation because reg clock_2 will 
initialize to 1'bx, and ~(1'bx) is 1'bx so the divisor will be
stuck at X.  It would work in synthesis.

My model works around the stuck-at-X problem without requiring
any explicit reset in simulation.  There are several other ways
to get the same effect, but the one I offered is probably the 
least hassle and the most portable across tools.  It will 
synthesise to just one flipflop and one inverter; I don't see
how you can do any better.

-- 
Jonathan Bromley

Re: Databus crossing clock domains with data freeze - Nicholas Kinar - 2010-01-07 10:18:00

Hello Jonathan--

Thank you once again for your detailed response.  This is very much 
appreciated.

> This really belongs on comp.lang.verilog, but the topic 
> has been flogged to death there; and Verilog users on 
> comp.arch.fpga may find it vaguely relevant.
> 

Sure, but I find that comp.arch.fpga tends to be slightly more active 
than comp.lang.verilog.  So when I weighed the possibilities of posting 
there, I thought that I would go with comp.arch.fpga because clock 
domain crossing is a topic that encompasses all work with FPGAs.

> 
> Error #1: Your model will never start running in
> simulation, because both regs initialize to 1'bX
> (as do all regs in Verilog) and the comparison
>    (old_slow_flag != slow_flag)
> evaluates to "unknown", because both sides of the
> equality are unknown.  When if() tests an unknown
> condition, it (by definition) takes the "else"
> branch; your code has no "else", so the if() 
> statement will do nothing.  Consequently the regs
> will remain stuck at X in simulation.  By contrast,
> synthesis can't handle X values and will give you
> the logic you expect; but that's probably wrong
> too, because....

I try to initialize registers so that everything is in a known state.

reg old_slow_flag = 0;
reg slow_flag = 0;

But your example code takes into consideration the 1'bX condition and is 
more robust.

> 
> Error #2: slow_flag is generated in the source
> clock domain, and therefore may not have enough
> setup and hold time relative to the target clock.
> Consequently you could get an input hazard:
> the comparator result (old != new), which is used
> to enable various flipflops, might be detected
> "true" by some of the flops and "false" by others.
> That's why I took care to resynchronize it.
> 

Okay, now I understand the reasons for resynchronization.


> 
> OK< so now let's go back to my example and see 
> (a) why it's right and (b) how I could recode it
> to be a little easier to follow.

Thank you for going over this line-by-line.


>   always @(posedge fast_clock) begin   // line 1
>     resync_slow_flag <= slow_flag;     // line 2
>     old_slow_flag <= resync_slow_flag; // line 3
>     if (old_slow_flag != resync_slow_flag) begin // 4
>       freeze_register <= source_data;
>       // Do other related things
>     end
>   end
>



> On line 2, we copy the asynchronous signal "slow_flag"
> into its resynchronizing register.  However, we use <= 
> nonblocking assignment, which means that the updating of
> resync_slow_flag is postponed until all other activity
> caused by the clock edge has finished.  This postponed
> signal update behaviour nicely models the clock-to-output
> delay of real flip-flops.  In particular, it means that...

This nicely explains what is happening with the non-blocking assignment.

> On line 3, we copy resync_slow_flag to old_slow_flag.
> But the value of resync_slow_flag that we copy HAS NOT YET
> BEEN UPDATED by the nonblocking assignment.

Ah! - okay.  This explains the behavior of the code.

   In other
> words, we get the flipflop's value as it was just before
> the clock edge.  Similarly, on line 4 the values tested
> by the if() expression are the values as they were just
> before the clock edge.  The same would be true if those
> values were tested in any other always block triggered by
> the same clock event; the value that you read is the value
> as it was just before (and also at the moment of) the clock 
> edge.  New values assigned using <= are projected future 
> values; they will take effect just after the clock edge 
> and, in particular, AFTER the execution of any always
> block that was triggered by the same clock.  This is 
> precisely how you get proper synchronous behaviour in
> Verilog RTL code.
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> However, some folk (particularly those coming from a
> software background, where assignments always update 
> their targets immediately) find this sort of thing a little
> awkward to read.

That would be me!


   So you can, if you wish, re-code the
> always block in a more software-like style provided you
> give it some local variables.
> 
>   always @(posedge fast_clock) begin : my_resync // 1
>     reg resync_slow_flag, old_slow_flag;         // 2
>     if (old_slow_flag != resync_slow_flag) begin // 3
>       freeze_register <= source_data;            // 4
>       // Do other related things                 // 5
>     end                                          // 6
>     old_slow_flag = resync_slow_flag;            // 7
>     resync_slow_flag = slow_flag;                // 8
>   end
> 

This is a nice example.


> By labelling the "begin" on line 1, we are entitled to
> declare local variables in the block (line 2).  Note that
> these variables are STATIC; they are NOT re-initialized
> each time the block executes, but instead they hold their
> value from its previous execution.
> On line 3 we test those variables' values; of course, the
> values we get are the values left over from the previous
> clock - that's flipflop behaviour.
> On lines 7 and 8 we update the variables using blocking
> assignment, which takes effect immediately.  Consequently
> we must respect your original concerns, and reverse the
> order of the two assignments so that the updating of
> old_slow_flag uses the old, rather than the updated, value
> of resync_slow_flag.
> 
> This use of local variables has a number of benefits.  We
> have hidden the variables resync_* and old_* inside the
> begin...end block where they're used, and they are not
> (easily) accessible by other code that shouldn't be 
> concerned with them.  We go back to a software-like model
> of execution in which local variables update instantly.
> However, we MUST continue to use nonblocking assignment
> to freeze_reg because it will be read by other blocks
> of code, outside this particular always block.  Whenever
> you write to a variable within a clocked process, and that
> variable will be read by any other process, it's essential
> to use nonblocking assignment in this way or else you will
> get catastrophic race conditions in simulation, and mismatch
> between simulation and synthesis behaviour.
> 



> Asks with trepidation..... where did you learn your Verilog,
> without finding out about the correct usage of <= ???


I am actually an environmental physicist who has had to self-teach 
myself Verilog and everything to do with FPGAs.  It is impossible to 
really grasp the nuances of the language, the technology and the ideas 
without participating in some sort of community, despite the 
proliferation of "crash-courses" and "learn HDL in a week" materials.

Such courses and books may get you started, but there is always a lack 
of experience.  That's the reason why I rely on your help and the help 
of other people on this newsgroup.




______________________________
Join the blogging team on FPGARelated.com and earn rewards! Details Here.

Re: Databus crossing clock domains with data freeze - Nicholas Kinar - 2010-01-07 10:27:00

>>>
>>>   always @(posedge slow_clock)
>>>     if (slow_flag == 1'b1)
>>>       slow_flag <= 0;
>>>     else
>>>       slow_flag <= 1;
>>>
>> I see - all that is being done here is a simple clock divisor.  Perhaps 
>> this could also be done with a shift register?
> 
> I'm not quite sure what you mean here.  In principle, the simplest
> possible clock divisor is
> 
>   always @(posedge clock)
>     clock_2 <= ~clock_2;
> 
> It is indeed a shift register; on each clock it shifts
> the inverse of itself into itself, and it has only 1 stage.
> 
> But this doesn't work in simulation because reg clock_2 will 
> initialize to 1'bx, and ~(1'bx) is 1'bx so the divisor will be
> stuck at X.  It would work in synthesis.

I'm fond of setting the register to zero when it is initialized

reg clock_2 = 0;

But I believe that some older versions of the Verilog language standard 
do not support this, and your code always ensures that this will work.

> 
> My model works around the stuck-at-X problem without requiring
> any explicit reset in simulation.  There are several other ways
> to get the same effect, but the one I offered is probably the 
> least hassle and the most portable across tools.  It will 
> synthesise to just one flipflop and one inverter; I don't see
> how you can do any better.
> 

Yes I agree - it's a very clean solution.



Re: Databus crossing clock domains with data freeze - Al Momen - 2010-02-07 08:33:00

>This really belongs on comp.lang.verilog, but
the topic 
>has been flogged to death there; and Verilog users on 
>comp.arch.fpga may find it vaguely relevant.
>
>On Wed, 06 Jan 2010 21:04:28 -0600, Nicholas Kinar wrote:
>
>>> What I don't understand is the assignment logic at the top of this 
>>> always block.  Isn't "old_slow_flag" equal to
"resync_slow_flag"?
>
>No, it's not.  I carefully and correctly used a nonblocking
>assignment <=, causing a delayed update of the target.
>Whatever else you do, please get a robust understanding
>of the relationship between blocking = and nonblocking <=
>assignment before you do anything further with Verilog.
> 
>>To help me better understand this, I've re-written the code:
>>
>>reg old_slow_flag;
>>reg slow_flag;
>>
>>always @(posedge fast_clock) begin
>>
>>     if (old_slow_flag != slow_flag) begin
>>
>>       old_slow_flag <= slow_flag;
>>       freeze_register <= source_data;
>>
>>       // Do whatever it takes to indicate that
>>       // source_data has been consumed, and make
>>       // the next source_data available no more
>>       // than 2 fast clocks later
>>
>>     end
>>   end
>
>OK, I see what you're saying, but I'm afraid it's 
>completely wrong.  I'm not quite sure how to respond
>to this, but as a first try I'll explain why your
>code is broken and then show you a slightly different
>(and perhaps clearer) way to organize the design I 
>first offered.
>
>Error #1: Your model will never start running in
>simulation, because both regs initialize to 1'bX
>(as do all regs in Verilog) and the comparison
>   (old_slow_flag != slow_flag)
>evaluates to "unknown", because both sides of the
>equality are unknown.  When if() tests an unknown
>condition, it (by definition) takes the "else"
>branch; your code has no "else", so the if() 
>statement will do nothing.  Consequently the regs
>will remain stuck at X in simulation.  By contrast,
>synthesis can't handle X values and will give you
>the logic you expect; but that's probably wrong
>too, because....
>
>Error #2: slow_flag is generated in the source
>clock domain, and therefore may not have enough
>setup and hold time relative to the target clock.
>Consequently you could get an input hazard:
>the comparator result (old != new), which is used
>to enable various flipflops, might be detected
>"true" by some of the flops and "false" by others.
>That's why I took care to resynchronize it.
>
>Subsequently you said that the fast clock is known
>to be exactly 4x the slow clock; indeed, with a PLL,
>you can get the slow clock's edges exactly lined up
>with the fast clock's and you don't need to worry 
>about clock domain crossing at all.  That somewhat
>changes the goalposts, but my original solution 
>remains valid even when the two clocks are completely
>asynchronous.
>
>OK< so now let's go back to my example and see 
>(a) why it's right and (b) how I could recode it
>to be a little easier to follow.
>
>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>THIS IS THE BIT THAT YOU REALLY MUST UNDERSTAND.
>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>  always @(posedge fast_clock) begin   // line 1
>    resync_slow_flag <= slow_flag;     // line 2
>    old_slow_flag <= resync_slow_flag; // line 3
>    if (old_slow_flag != resync_slow_flag) begin // 4
>      freeze_register <= source_data;
>      // Do other related things
>    end
>  end
>
>On line 1, the always block waits for the next clock 
>edge.  So far, so good.
>On line 2, we copy the asynchronous signal "slow_flag"
>into its resynchronizing register.  However, we use <= 
>nonblocking assignment, which means that the updating of
>resync_slow_flag is postponed until all other activity
>caused by the clock edge has finished.  This postponed
>signal update behaviour nicely models the clock-to-output
>delay of real flip-flops.  In particular, it means that...
>On line 3, we copy resync_slow_flag to old_slow_flag.
>But the value of resync_slow_flag that we copy HAS NOT YET
>BEEN UPDATED by the nonblocking assignment.  In other
>words, we get the flipflop's value as it was just before
>the clock edge.  Similarly, on line 4 the values tested
>by the if() expression are the values as they were just
>before the clock edge.  The same would be true if those
>values were tested in any other always block triggered by
>the same clock event; the value that you read is the value
>as it was just before (and also at the moment of) the clock 
>edge.  New values assigned using <= are projected future 
>values; they will take effect just after the clock edge 
>and, in particular, AFTER the execution of any always
>block that was triggered by the same clock.  This is 
>precisely how you get proper synchronous behaviour in
>Verilog RTL code.
>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>However, some folk (particularly those coming from a
>software background, where assignments always update 
>their targets immediately) find this sort of thing a little
>awkward to read.  So you can, if you wish, re-code the
>always block in a more software-like style provided you
>give it some local variables.
>
>  always @(posedge fast_clock) begin : my_resync // 1
>    reg resync_slow_flag, old_slow_flag;         // 2
>    if (old_slow_flag != resync_slow_flag) begin // 3
>      freeze_register <= source_data;            // 4
>      // Do other related things                 // 5
>    end                                          // 6
>    old_slow_flag = resync_slow_flag;            // 7
>    resync_slow_flag = slow_flag;                // 8
>  end
>
>By labelling the "begin" on line 1, we are entitled to
>declare local variables in the block (line 2).  Note that
>these variables are STATIC; they are NOT re-initialized
>each time the block executes, but instead they hold their
>value from its previous execution.
>On line 3 we test those variables' values; of course, the
>values we get are the values left over from the previous
>clock - that's flipflop behaviour.
>On lines 7 and 8 we update the variables using blocking
>assignment, which takes effect immediately.  Consequently
>we must respect your original concerns, and reverse the
>order of the two assignments so that the updating of
>old_slow_flag uses the old, rather than the updated, value
>of resync_slow_flag.
>
>This use of local variables has a number of benefits.  We
>have hidden the variables resync_* and old_* inside the
>begin...end block where they're used, and they are not
>(easily) accessible by other code that shouldn't be 
>concerned with them.  We go back to a software-like model
>of execution in which local variables update instantly.
>However, we MUST continue to use nonblocking assignment
>to freeze_reg because it will be read by other blocks
>of code, outside this particular always block.  Whenever
>you write to a variable within a clocked process, and that
>variable will be read by any other process, it's essential
>to use nonblocking assignment in this way or else you will
>get catastrophic race conditions in simulation, and mismatch
>between simulation and synthesis behaviour.
>
>Asks with trepidation..... where did you learn your Verilog,
>without finding out about the correct usage of <= ???
>-- 
>Jonathan Bromley
>
Hello Jonathan,

I have simulated your code, however, I am only capturing every other databeats or the Even Data ( i.e. 0,2,4,6,8,..) the Odd Data beats are lost.

My Slow clock is (slow_period >= (2*fast_period) + (2/Fmax)) as an exampleFast clock 100Mhz, slow Clock at 48Mhz. The source data are bursts in atthe Fast clock frequency.

From your solution, it seems the source data are been sampled at slow_flagor at the half of the fast clock rate. This will drop the second beats orOdd data beats ( 1,3,5,7,.. Data Beats)
Please clarify, if I am missing something?






	   
					
---------------------------------------		
Posted through http://www.FPGARelated.com
______________________________
Join the blogging team on FPGARelated.com and earn rewards! Details Here.

Re: Databus crossing clock domains with data freeze - Jonathan Bromley - 2010-02-07 09:45:00

On Sun, 07 Feb 2010 07:33:49 -0600, "Al
Momen" wrote:

>I have simulated your code, however, I am only capturing every other data
>beats or the Even Data ( i.e. 0,2,4,6,8,..) the Odd Data beats are lost.
>
>My Slow clock is (slow_period >= (2*fast_period) + (2/Fmax)) as an example
>Fast clock 100Mhz, slow Clock at 48Mhz. The source data are bursts in at
>the Fast clock frequency.
>
>From your solution, it seems the source data are been sampled at slow_flag
>or at the half of the fast clock rate. This will drop the second beats or
>Odd data beats ( 1,3,5,7,.. Data Beats)
>Please clarify, if I am missing something?

I'm confused: do you get data on every cycle of the 100MHz clock?
If so, then you cannot expect to get every data item across
the interface unless you add some buffer storage (FIFO) on the
fast, source side.  The original question, for which I wrote
the specific answer, was about data transfer _with data freeze_;
in other words, the source data must be held until the slow,
target clock domain has taken it.  Clearly you can't do that
if you have new data on every cycle of the fast source clock.

FIFO storage allows you to buffer up a fast burst and then
transfer it slowly while the source is inactive.  But
that's not what the original question was about.  It
sounds as though your application needs a full-dress
two-clock FIFO.
-- 
Jonathan Bromley

previous | 1 | 2