LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

FIFO across clock domains

I'm using a FlexRIO 7966R for digital signal manipulation and need to buffer data across clock domains. By buffer I mean I need to be able to store in memory a variable amount of data before it's read back out in order to achieve a data delay. I can successfully write to the FIFO in one clock domain and read data from the FIFO in another clock domain, but as soon as I introduce the "Get Number of Elements to Read" function the compilation fails with a timing violation. It appears that this method cannot execute quickly enough:

 

FIFO_cross_clock_domains.PNG

 

I tried moving the "Get Number of Elements to Read" function into another slower clock domain SCTL but the compiler then states that it has to be in the same clock domain as the Read FIFO function, so that doesn't help.

 

Any thoughts anyone?

Thoric (CLA, CLED, CTD and LabVIEW Champion)


0 Kudos
Message 1 of 14
(4,510 Views)

Hi!

 

What adapter module are you using? I'm curious as to what rate Data Clock x2 is running at.

Rob B
FlexRIO Product Manager
0 Kudos
Message 2 of 14
(4,507 Views)

Well it looks like the clock rate is 250MHz based on the 4ns requirement. What is the FIFO data type set to? Is it possible that you could bitpack the data and then perform your processing on multiple samples per cycle? 

 

Rob B
FlexRIO Product Manager
Message 3 of 14
(4,502 Views)

You could try counting the number of samples that you insert into the fifo and then pull them out of the fifo once that number hits a threshold.

 

fifo_read.png

 

 

Message 4 of 14
(4,486 Views)

Do you really need to know the number of elements in the queue?

 

I believe the help mentions something about certain fifo functions requiring more resources.

 

I would split the functionality into two parts.

1) domain crossing with FIFO

2) impkement on the receiver or sender side a BRAM circular buffer with controllable read/write index difference (thus changing the delay).  Your BRAM needs to be big enough to hold the largest delay required.  Ive done this at 160 MHz on a virtex 5 target.

Message 5 of 14
(4,461 Views)

Thank you everyone for your posts.

 

The Data Clock rate is 250MHz, and therefore Data Clock x2 is 500 MHz.

 

Yes, I need to now how many are in there as the FIFO as a delay buffer for our signal. The length of delay needs to be confiigurable, therefore the Read operation must occur only when sufficient samples are stored in the FIFO.

 

As the two loops are synchronised, I know I can operate a custom counter in the slower loop that compares against the required number of buffered samples. I'm trying an implementation and will report back when I see how it performs.

Thoric (CLA, CLED, CTD and LabVIEW Champion)


0 Kudos
Message 6 of 14
(4,414 Views)

I still think a bram circular buffer is useful here.  Controlling both the write and read indices, you have complete control over the delay in a really simple manner.

0 Kudos
Message 7 of 14
(4,408 Views)

@Intaris wrote:

I still think a bram circular buffer is useful here.  Controlling both the write and read indices, you have complete control over the delay in a really simple manner.


I'm interested in hearing more on why you advocate BRAM here. I'm not saying you're wrong, but a local variable works fine so long as I write to it in only one domain. BRAM can't cross clock domains (High-Throughput LabVIEW Course Material) so I can't use in here?

 

So far I've tried this and it compiles without issue, but I need to work on it to allow better control of when to stop acquiring in the case where the required number of buffered samples needs to reduce.

FPGA_custom_counter.jpg

Thoric (CLA, CLED, CTD and LabVIEW Champion)


0 Kudos
Message 8 of 14
(4,390 Views)

Correct, BRAM does not cross clock domains. This is why i proposed splitting the work into two parts, domain crossing and delay.

 

Using the BRAM on the receivinG side only you can implement a circular buffer of size x with write index incremented each cycle and the read position is relative to this.  By changing the offset between write and read (all on the receiver side) you can implement any delay up to x.  Your receiver order would be read FIFO (in every cycle), write to BRAM, read from BRAM and continue.

 

That way your FIFO for crossing domains can be much smaller, saving LUTs and registers.

 

Regarding recucing the delay: If your sender is sending data as fast as your receiver can read them, reducing the delay sounds like it is always going to be lossy.  You can do this with the BRAM by adjusting the offset between write and read accordingly, effectively skipping data.

 

Im in the mountains on holiday so i cant post code for another week.....

 

Other topic.... I though the max clock on a 7966 was 326 MHz? I know on a 7965 its listed as 326 MHz.

0 Kudos
Message 9 of 14
(4,384 Views)

@Intaris wrote:

Correct, BRAM does not cross clock domains. This is why i proposed splitting the work into two parts, domain crossing and delay.

 

Using the BRAM on the receivinG side only you can implement a circular buffer of size x with write index incremented each cycle and the read position is relative to this.  By changing the offset between write and read (all on the receiver side) you can implement any delay up to x.  Your receiver order would be read FIFO (in every cycle), write to BRAM, read from BRAM and continue.

 

That way your FIFO for crossing domains can be much smaller, saving LUTs and registers.

 

Regarding recucing the delay: If your sender is sending data as fast as your receiver can read them, reducing the delay sounds like it is always going to be lossy.  You can do this with the BRAM by adjusting the offset between write and read accordingly, effectively skipping data.

 

Im in the mountains on holiday so i cant post code for another week.....

 

Other topic.... I though the max clock on a 7966 was 326 MHz? I know on a 7965 its listed as 326 MHz.


Thanks for the insight Intaris.

My FIFOs are set to use BRAM, so will your proposal of creating a small FIFO for crossing the clock domains plus a separate BRAM block for buffering achieve much saving in fabric? Isn't that the same amount of BRAM, plus a bit for your FIFO? I might go ahead and create a test implementation to see the difference in FPGA resource usage...

 

I'm using a 5782 Module with independent 500MHz clock.

 

 

Thoric (CLA, CLED, CTD and LabVIEW Champion)


0 Kudos
Message 10 of 14
(4,370 Views)