IF-RIO

cancel
Showing results for 
Search instead for 
Did you mean: 

Synchronization of the DDC chain pci 5640R

Hi everybody, I've got a PCI-5640R board.

I need to synchronize the DDC chain of this board with an external

asynchronous trigger, acquired from the TRIG_IN pin.

I try to explain this in a better way: I'd like to acquire the

asynchronous trigger with a Timed Loop ("clocked" with RTSI=100MHz) and then to " reset" the generation of the clocks used to sample the analog signals from ADC_0 and ADC_1, that is, I'd like that all the rising edges of the clocks I use in the DDC chain should be synchronous with the rising edge of the trigger ( or at least with the rising edge of the RTSI clock that detect the rising edge of the trigger).This operation should be realized on the FPGA vi and not from the Host vi.

I tried with a START SYNCHRONIZATION (see AD6654 data sheet, page 58) realized on the FPGA vi but I am not sure this is the better way...

Thanks in advance for your help

Best regards

Luca

0 Kudos
Message 1 of 9
(10,373 Views)
Hi Luca
 
Can you provide a few more details on what you are asking for?  We are not sure if what you are asking for is possible, but we want to make sure. 
 
Thanks
Jerry
Message 2 of 9
(10,323 Views)

Hi Jerry,

Let's start from the beginning:

Top level clock= configuration clock (20 MHz)

RTSI clock= 100 MHz, ADC0 clock=2MHz, ADC1 clock=20MHz

1. We acquired a trigger signal (Pulse Repetition Time = 1.056 ms typical, duty cycle = 0.1 %) with a SCTL running at 100 MHz.

2. When the trigger goes high we have to acquire 1 ms (< PRT of the trigger) from: ADC0 (2 MHz signal so 2000 samples) , ADC1 (20MHz signal so 20000 samples).

We tried to do this using global variables as control flags as you can see from the FPGA vi I attached. The problem is that sometimes it seems that the global variable that enable the acquisition inside the ADC1 SCTL is read with a delay of 4 samples. Should it be a problem of handshaking? How can we solve it?

The second problem is related with the former one: we want that the time delay that elaps from the rising edge of the trigger and the first sample from ADC1 and ADC0 should be as constant as possible. So we have thought that we had do a re-synchronization of the clocks. We have realized a vi that does this from the FPGA vi: it does what the "ADC read write register (multiple byte).vi " does....I attached it

In simple terms the vi we realized does a soft synchronization and it seems something happen but we are not sure of the results..

I hope I described our work in a better way...

Best regards

Luca, Emanuele

0 Kudos
Message 3 of 9
(10,303 Views)
Hi Luca
 
This is a hard one.  There is a delay on writing to a variable and then reading from the variable in a different single cycle loop.  It can actually be random up to two or three clock cycles for each loop (write and read).  So there will be a delay in what you are trying to do.
 
The only suggestion I have at this point is to actually acquire data from both ADCs at the same higher rate.  Place both the ADC reads into the same single cycle loop.  Then decimate the data from the ADC that you want to clock at 2 MHz.  Saving one for every 20 samples.
 
You may also want to add the Trigger detection if possible as well.
 
Another issue is the 2 MHz and 20 MHz rates themselves.  How are you setting the ADC and single cycle clock loop rates?  The ni5640R ADC Configure DDC.vi that runs on the host doesn’t have a decimation rate that will match up with 2 MHz or 20 MHz (assuming the ADC is clocked at 100 MHz on the input).  The decimation values are powers of 2.  The closets you can get to 20 MHz is 100/4 = 25 MHZ, or 100 / 8 = 12.5 MHz.
 
Jerry
Message 4 of 9
(10,260 Views)
Hi Jerry,
 
thanks for your help.
 
Actually we are trying to change our approach to the problem in the way you suggested. Well we are trying to use only the SCTL with the 100MHz clock and then acquire the ADC1 every 5 ticks and the ADC0 every 50 ticks.. but we are facing problem with Timing violation....in case we are not able to solve it we send you a post...maybe you can help us.
 
To reply to your question about 2MHz and 20 MHz clocks we changed the ni5640R ADC Configure DDC.vi  creating a custom version to fit our needs. Basically we added two cases in the decimation rates: 5  (100MHz/5=20MHz) and 50 (100MHz/50=2MHz).
The former is realized implementing only the 5^ order CIC with a decimation factor = 5 and disabling the others filters (we do not care too much of the 20 MHz flow in term of rejection).
The latter, instead, is realized implementing:
  • CIC with dec_rate=5;
  • FIR1 enabled;
  • HB1 disabled;
  • FIR2 enabled;
  • HB2 disabled;
  • MRCF enabled: we created, with Matlab, this 7 taps symmetrical filter and we use this as a pre-compensator filter;
  • DRCF enabled with dec_rate=5: we created, with Matlab, this  49 taps symmetrical filter;
  • CRCF enabled with dec_rate=2: we created, with Matlab, this  99 taps symmetrical filter;

So, Total_dec_rate= 5*5*2=50  and the result in term of rejection is good 

Anyway We attached the custom vi and the coefficents hmrcf_q, hdrcf_q, hcrcf2_q with q=quantized in the folder Data

Luca, Emanuele

0 Kudos
Message 5 of 9
(10,253 Views)
Sorry,  here is  the file
0 Kudos
Message 6 of 9
(10,251 Views)
Hi Emanuele
 
Actually, I’m not sure that your method will work.  There are two issues here now. First, the synchronization between the two ADCs is still going to be troublesome because they are running off of two different DDC clocks.  The second is that you have a 20 % (20 MSps ADC) and 2% (2 MSps ADC) of not getting the correct IQ pair when you start the program. 
 
For example, based on the following image (not drawn completely to scale) based on the 20 MSps ADC.  The ADC’s I, Q, and Gain values are clocked out of the ADC serially.  So, if the clock is being driven by the 100 MHz clock (default), the I, Q, and Gain are clocked out to the FPGA registers on successive clocks of the 100 MHz.  In the image, let’s assume that this happens on the rising edge of the 100 MHz clock.  The LabVIEW FPGA IO nodes will read the values from the FPGA registers on the clock you have running the single cycle timed loop.  Let’s assume that this happens on the falling edge of the 100 MHz clock.
 
 
The issue is that you can not guarantee which falling edge of the 100 MHz clock that you read the I and Q values.  If the program/FPGA starts and you happen to read the data on the falling edge between the times that the I value and Q value are written to the registers, you will have an IQ pair in which the I is new data and the Q is from the previous acquired sample.  The data will be skewed.  For a 20 MHz clocking, this can happen once out of every 5 cycles.  So, the data can be bad 20 % of the time.  Since everything is clocked, it will be bad for the entire run.  Stopping and starting again will have it start getting data on another random edge.
 
For the case of the 2 MHz ADC, the chance of getting this bad spot is 2%.
 
In my suggestion, the ADCs are both running at 20 MSps.  This way they will both respond as close to each other as possible when you want data.  Then you throw away 19 of every 20 samples to get the 2 MSps rate.  This may require more filters in the LabVIEW FPGA to ensure the data is good enough for you.
 
Jerry

Message Edited by Jerry_L on 02-06-2007 04:11 PM

Message 7 of 9
(10,243 Views)
Hi
 
Another issue that must be set is to synchronize the ADCs.  I don’t have an example, but the following steps should get you up and running.
 
1. On the FPGA VI, the "acquire" control is used to start the acquisition.  However, on one single cycle timed loop (SCTL) you read from the actual control while in the other SCTL you read from a local variable.  The control and the local variable don't get updated at the same time.  So one acquisition could be starting sooner than the other.  So both acquisitions need to be put inside one SCTL and then make sure that the clocks for both channels are synchronized. To ensure that the clocks are synchronized is not very straight forward. This is the process that you need to do:
 
a) Add the RTSI Clock to your project
 
b) Change the configuration loop so it runs on the RTSI Clock
c) In your FPGA diagram, add this code inside the configuration loop:
 
 
Change the mechanical action of the boolean control "Config.ADC Sync" to "latch when release".
 
d) Set the "Config.ADC Simultaneous Programming" to TRUE. After doing this, you don't have to call every VI twice (one for each ADC), since both ADCs are being programmed with the same commands.
 

e) Open the VI "ni5640R ADC Sync" and modify it so instead of calling the "ni5640R ADC 05 - Soft Sync.vi" it calls the "ni5640R ADC 04 - Pin Sync.vi" (only once) with the following inputs:
 

f) After the call to the ""ni5640R ADC 04 - Pin Sync.vi" vi, add a read/write node to write to the "Config.ADC Sync" control that you added in step "c" and wire a TRUE constant.

Message Edited by Jerry_L on 02-07-2007 10:21 AM

Message 8 of 9
(10,224 Views)

Hi Jerry

This is great day for us.....the system works!!!!!!

Before I try to explain what we have done let me thank you for the time you spend trying to understand and solve our problems.

We had not seen your last replay but that is a sort of confirmation of what we did.

We solved our problem with global variables.... we don't use them all....

The FPGA.vi has been structured as follow:

      a stack sequence with 2 frame: the former with the configuration timed loop but with RTSI=50MHz (we used this to set all the values from the host.vi like NCO freq.....etc ). The latter is a while loop with inside it another stack sequence with 3 frame:

      the first is a SCTL with RTSI =50 MHz used to sample the trigger: when the system see a rising edge from the trigger the SCTL is stopped end the control goes to the next frame

      this second frame is the most important one. Inside a SCTL we perform a Soft sync on the ADC clocks. The way we do this is similar to that we show you in the sub_vi "Soft_sync" we attached the first time. The only difference is that we no more use the global variable: we use directly the node to the registers like ADC_0_Microport_Addr and so on...the thing to pay attention is that we change the arbitration mode of this registers: from Arbitrate if multiple access only to Never arbitrate. The way you described in the post seems to be easier...maybe we'll try it.

      the third frame has inside 2 parallel frame sequence with some frames: one for the ADC0 flow @ 2 MHz and one for the ADC1 flow @ 20 MHz

If you want we can send you the vi by mail, unfortunately we cannot post it

Thank you very much

Best regards

Luca, Emanuele

0 Kudos
Message 9 of 9
(10,200 Views)