Capturing ADC Data using LVDS interface - Page 1
Forum section: electronics / general

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: May 25, 2021, 09:31:56 am
content: Hi,This is my first time connecting a LVSD ADC (AFE5816) to an Spartan 6 device, I want to make sure I'm doing everything just right,This is the schematic for the ADC, it’s connected to Bank 0 of the FPGA,So I want to use the coregen for capturing the ADC, DATA, this is the tricky part, what settings should I put in here? Is these setting in the Picture, correct?Any help or sample project or code can really comes in handy.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: May 26, 2021, 05:46:03 am
content: Any one with another LVDS ADC experience in here?

author: aandrew
author_rank: Frequent Contributor
timestamp: May 26, 2021, 04:41:07 pm
content: I used the LTC2387 which is a 1- or 2-lane DDR output ADC (I used only one lane) with a MAX10. The tricky bit for me was using the returned clock along with the data lane and do the DDR to SDR conversion in the FPGA.For you, I suspect that as long as you make sure that your LVDS inputs are all actually going to pins that are a) correctly paired and b) can be constrained to meet timing, you'll be golden. It looks like you're using the FPGA to serialize the data, rather than use it in the FPGA itself. I was doing the opposite (deserializing the ADC data and embedding it in gigabit ethernet frames along with other information).Just double and triple check the FPGA datasheet, configure all the pins in Vivado, write the timing constraint file and make sure that the FPGA will actually do what you ask it to do; I've been surprised by "special cases" where an LVDS input pair could not be used because I was using some other I/O standard on the same bank (even with the same VDDIO), or that an LVDS input pair was actually emulated LVDS, which meant that its timing was worse than the rest of the pairs and made timing closure trickier, that perhaps the PLL I was using couldn't actually send its output to that specific GCLK, etc., etc. Test everything before going to layout. :-)Oh - I don't see any termination resistors; does your FPGA have internal termination? I had to sprinkle my LVDS lines 100R 0201 resitors just outside the FPGA's courtyard.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: May 27, 2021, 05:26:17 am
content: QuoteThanks for the info, I'm doing exactly something like you, Capturing ADC data and sending them using Ethernet, ANy hint on how to deserilize the ADC, this is the first time I'm using LVDS and I have no experience in there.

author: Bassman59
author_rank: Super Contributor
timestamp: May 27, 2021, 05:32:12 pm
content: Quote from: ali_asadzadeh on May 27, 2021, 05:26:17 amLVDS simply defines the I/O standard or type: it means a differential pair of wires carries the signal, and the signal swing is 300 or so millivolts about a DC offset of 1.25 V. It says absolutely nothing about what sort of information is carried on the wire pair. It says nothing about whether the wires carry serial data or one bit of a parallel data bus or a clock or even whether the data are coded in an interesting way or not.So your question is really, "how to deserialize the ADC data, given the data format documented in the device data sheet."

author: BrianHG
author_rank: Super Contributor
timestamp: May 28, 2021, 04:33:08 am
content: Quote from: aandrew on May 26, 2021, 04:41:07 pmThe limited quantity true LVDS inputs available on all MAX10/Cyclone devices do have a software programmable internal 100 ohm terminator. The emulated LVDS_E_3R available on almost all IOs do not. Though, with 16 differential channels, you probably had to use the emulated LVDS inputs.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: May 28, 2021, 12:23:06 pm
content: BrianHG, Thanks for the feedback, I'm using spartan6, do you have any input on spartan6, any help would be appreciated.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: May 28, 2021, 12:29:24 pm
content: QuoteThere is nothing fancy about the ADC, it just put data @ 1Gbps at outputs, and I should use SEREDES inside the Spartan 6 IO to convert them to parallel data at lower frequency, and since I have not done it before, I do not know how to do it yet. so have you any experience and are you willing to help?

author: RoGeorge
author_rank: Super Contributor
timestamp: May 28, 2021, 12:45:06 pm
content: It's SERDES, stands for dataserialiser/deserialiser block, not SEREDES.What do you call a SEREDES?LATER EDIT:It felt like a deja vu while typing the above, so googled to check if indeed I've said that before.Turned out indeed I've wrote that before, and guess to whom?https://www.eevblog.com/forum/projects/why-we-can-not-have-more-than-5ghz-processors/msg3461062/#msg3461062

author: aandrew
author_rank: Frequent Contributor
timestamp: May 28, 2021, 04:51:40 pm
content: The output of his ADC is already parallel, he doesn't need to serialize anything. Bring in the IO, synchronize and use it in the FPGA.edit: I'm an idiot, I did not read the datasheet correctly. This does need to be deserialized.

author: NorthGuy
author_rank: Super Contributor
timestamp: May 28, 2021, 04:58:08 pm
content: It's all in the figure 1 of the datasheet.The ADC gives you two clocks - FCLK (start of the frame at the rising edge). DCLK which is 7 times faster than FCLK and is used to transmit DDR data (14 bits per one tick of FCLK).To parallelize the data you would need 1:14 SERDES. You would feed FCLK, DCLK and the DOUT to it and it would produce 14 lines of parallel data in FCLK domain.I don't think Spartan-6 has 1:14 ISERSDES (but I think Spartan-7 does). So, you may need to improvise - such as one 1:7 SERDES for rising edges of DCLK and one 1:7 SERDES for falling edges of DCLK. Or 1:7 DDR ISERDES (but it'll require FCLK/2 clock) followed by 1:2 SERDES in the fabric. Such solutions may or may not be routable. It's up to you to explore.

author: NorthGuy
author_rank: Super Contributor
timestamp: May 28, 2021, 05:10:06 pm
content: Or you may try to work directly in DCLK domain. Instead of ISERDES, you use IDDR input element which deserializes DDR data 1:2 and then you deserialize the rest in the fabric. You also sample FCLK to figure out where the frame starts. It is easy, but will work only if DCLK is slow enough to clock the fabric.

author: asmi
author_rank: Super Contributor
timestamp: May 28, 2021, 05:41:30 pm
content: Quote from: NorthGuy on May 28, 2021, 05:10:06 pmDid you look at the datasheet? It's got 16 independent serial LVDS channels, up to 1 Gbps each. No way you will do anything with IDDRs. Even much faster Spartan-7 won't be able to keep up. So using ISERDES is mandatory. I don't remember if S6 can do 1:12 or 1:14 deserialization, if it can't, you will have to use some sort of gearbox and intermediate frequency.The more interesting question is what OP is planning to do with all this data. We're talking about a continuous 16 Gbps data stream, so not even 10G Ethernet is going to be fast enough to stream it out unless some preprocessing with significant data reduction is going to be performed inside FPGA. Also - I seem to recall that S6 can only run DDR3 at 333 MHz (unless you get your hands on rare SG3 devices), so you will need to use 64 bit DDR3 interface if you want to do some buffering, anything less won't allow simultaneous reading and writing. Of course all of that is based on assumption that you will have to max out sampling rate and actually use all 16 channels simultaneously.

author: NorthGuy
author_rank: Super Contributor
timestamp: May 28, 2021, 06:18:18 pm
content: Quote from: asmi on May 28, 2021, 05:41:30 pm1 Gbps requires 500 MHz clock. But the actual rate depends on the ADC speed. Say, if ADC samples at 50 Ms/s, DCLK is only 350 MHz. Spartan-6 should be able to run BUFG at 350 MHz. Thus the IDDR solution might be in reach.

author: asmi
author_rank: Super Contributor
timestamp: May 28, 2021, 06:35:08 pm
content: Quote from: NorthGuy on May 28, 2021, 06:18:18 pmOf course.Quote from: NorthGuy on May 28, 2021, 06:18:18 pmYeah, well, you might as well run that ADC at 1 MHz too. But what's the point of using such overkill ADC in the first place?BTW, as per datasheet, max rate for IDDR is 750 Mbps for SG2. But since the actual data size is 12 or 14 bits, you will have to have some sort of gearbox to further deserialize the data into actual data words, with all complexities it brings along, like additional clock domain. So using IDDR in this case makes even less sense, because ISERDES does it all out of box with no custom logic required, and no messing with CDC.

author: langwadt
author_rank: Super Contributor
timestamp: May 28, 2021, 07:11:15 pm
content: Quote from: asmi on May 28, 2021, 05:41:30 pmit's been a while since I used an S6 but I seem to remember max for iserdes is ~700Mbps (In my case 50Msps * 14bit)

author: NorthGuy
author_rank: Super Contributor
timestamp: May 28, 2021, 08:53:38 pm
content: Quote from: asmi on May 28, 2021, 06:35:08 pmIDDR and ISERDES is the same thing - ILOGIC. The difference is when it's configured 1:2 it's called IDDR, and when it's configured 1:n it's called ISERDES and requires separate CLKDIV.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: May 29, 2021, 06:42:21 am
content: QuoteIt's a serializer inside each IP pin

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: May 29, 2021, 06:47:31 am
content: QuoteI need to do it inside spartan 6, that's a requirement from customer, also I should average ADC readings to reduce it to about 1MSPS, so the data rate is low enough.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: May 29, 2021, 06:50:57 am
content: Thanks guys for the feedback, specially NorthGuy and asmi, do you have some sample code or code snippets? maybe I can talk to customer to lower sample rate to say 40 or 50MHz.

author: NorthGuy
author_rank: Super Contributor
timestamp: May 29, 2021, 03:16:20 pm
content: If you cannot summon 1:14 hardware ISERDES, making your own is very easy. The serdes is just a shift register. Something like this:Code:parallel: unsigned(13 downto 0);serial: unsigned(13 downto 0);process(fclk)beginif rising_edge(fclk) thenparallel <= serial; -- or use it directly (e.g. connect to FIFO clocked by fclk)end if;end process;process(dclk)beginif rising_edge(dclk) thenserial <= serial(11 downto 0)&iddr_q0&iddr_q1; -- for MSBend if;end process;If you only want 1 MSps rate, it's better to take a slower ADC.

author: langwadt
author_rank: Super Contributor
timestamp: May 29, 2021, 03:35:10 pm
content: Quote from: ali_asadzadeh on May 29, 2021, 06:50:57 am12 or 14 bits?

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: May 30, 2021, 05:55:44 am
content: QuoteThanks for the sample code, The costumer needs this ADC, He wanted to capture with higher data rate and then Make some averages,Quote14 bit