UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Explorer
Explorer
2,199 Views
Registered: ‎08-21-2013

Can I use SelectIO to read serialized LVDS ADC?

I'm converting a project from Altera and attempting to port the code that reads a 16-bit 20 MSPS ADC via serialized LVDS to an Artix 7 and Zynq. On Altera, I used ALTLVDS_RX which handles most things for me. In searching these forums and other places, I've come across a number of solutions such as XAPP524 and XAPP1017. These describe manually constructing the necessary ISERDESE2, IDELAYE2 and other cores along with state machines to align the data.

 

But it looks to me like I could just use the SelectIO IP setup something like below (I would append two 8-bit outputs to get the 16-bit ADC data). It even allows inserting delays per bit if I needed to (something Altera did not have). Is there some reason to follow XAPP1017 instead of just using this IP?

One thing that is not clear from the SelectIO docs is the assumed clock alignment. The bit clock, which is at 160 MHz) out of the ADC is already centered on the data (see below), but the SelectIO docs seem to assume the clock is aligned with the data. Do I need to add delay to the clock in the SelectIO wizard to center it?

Does Xilinx have anything like Altera DPA (Dynamice Phase Alignment)? I don't think I need it, but it was nice to have.

SelectIO.jpgADC_clock.jpg

 

 

 

0 Kudos
13 Replies
Highlighted
2,118 Views
Registered: ‎01-22-2015

Re: Can I use SelectIO to read serialized LVDS ADC?

@corestar

I posted a reply to you the other day – but then erased it since I had talked about a Single-Data-Rate (SDR) interface and your interface is Double-Data-Rate (DDR).  My reply was also not an answer to your question about the SelectIO IP.  Rather, I was encouraging a back-to-basics approach (ie. not using IP) since Source-Synchronous-Input can usually be done with simple architecture.  Not using IP makes your solution more portable, which you might want since you are working in both the Vivado and Quartus worlds.

Since nobody is answering your SelectIO question (and I can’t either), maybe you won’t mind talking about the back-to-basics solution. Hopefully, Avrum will keep an eye on us and correct us when we go astray.

First, a back-to-basics architecture for SDR input is shown below. The MMCM clock module accepts the LVDS data-clock, DCLKN/DCLKP, from your ADC and outputs a clock of the same frequency.  Use of the MMCM also allows you to shift the data-clock, placing the clock capture-edge in the middle of the data-eye. Finally, the MMCM does something called “delay compensation”, accounting for PVT variations of circuits between the DCLK inputs and the MMCM and keeping a constant phase relationship between DCLK and the MMCM output clock.
DDR_IN1.jpg

For the SDR input are a few needed constraints:

set_input_delay -clock DCLKP -max X.X [get_ports SDATP]
set_input_delay -clock DCLKP -min Y.Y [get_ports SDATP]
set_property PHASESHIFT_MODE LATENCY [get_cells FWCLK/inst/mmcm_adv_inst]

The last constraint allows you to enter phase-shifts during setup of the MMCM and have them interpreted as clock delays (needed to center capture-edges of DCLK in the data-eye).  From your Quartus work, you probably know how to calculate delays, (X.X and Y.Y), for the set_input_delay constraints. You might have expected a create_clock constraint, but this is automatically written for you when you setup the MMCM.

Then, I started thinking about the back-to-basics solution for your DDR input – and realized that I was not sure about the architecture - and couldn't find examples.  So, I came up with two possible(?) designs (I hope Avrum is watching):

  • Design-1:  Same as the circuit shown above except that frequency of the MMCM output clock is double that of DCLK.
  • Design-2:  The circuit shown below, where the MMCM operates the same as in the SDR design and the IDDR block allows you to capture data on both rising and falling edges of DCLK.

DDR_IN2.jpg

Again, there are a handful (or maybe more than a handful) of constraints to be written (see Avrum’s post <here> for details).

So, although I have experience with the back-to-basics solution for SDR input, I find myself in unfamiliar territory with the back-to-basics solution for DDR input. I hope my comments start a discussion that helps both of us.

Cheers,
Mark

Tags (1)
Explorer
Explorer
2,083 Views
Registered: ‎08-21-2013

Re: Can I use SelectIO to read serialized LVDS ADC?

markg@prosensing.com

 

Thanks for the detailed reply. I think there are many reasons to prefer IP over custom solutions, but I completely agree it is useful to understand what is going on under the hood and you've given me alot to think about. I'm afraid the Altera and Xilinx architectures are so different, complete portability is not possible.

Figuring this out is the last hurdle before making a final decision to ditch Altera and move to Xilinx. In the interest of expediency, I'm trying SelectIO IP first and will optimize later.

 

 

0 Kudos
Historian
Historian
2,072 Views
Registered: ‎01-23-2009

Re: Can I use SelectIO to read serialized LVDS ADC?

So first, Xilinx does not have the equivalent to the DPA of the Altera core. The only exception was the Spartan-6 which had some features of the IDELAY that could be easily converted to a DPA for clock centered data...

In terms of general philosophy, Xilinx goes more for providing low level primitives with a lot of information for the designer to engineer solutions. Altera more often went the way of providing more canned solutions, but without giving as much detail on some of the lower level architectural details. Both approaches have their merits, and this is a good example of the difference.

Next, on to some of the more concrete questions. The first question to ask is "can this interface be captured statically". In other words, is the width of the data valid period from the ADC large enough so that it can reliably be captured with static settings. If the answer is "yes", then this is a fairly simple problem to solve. If the answer is "no", then you need some kind of calibration and the APP notes give you some hints as to how to construct one.

Answering the question about whether it can be captured statically is only "completely" answered by implementing the solution with proper constraints and asking the tool "does it meet timing". But there are a couple of intermediate steps. The first is simply knowing what the device is capable of, and how fast your interface is. It appears that your interface is 160MHz DDR - this means that every bit lasts 3.125ns. Next you need to know the uncertainty of the clock data relationship from the ADC - essentially how much of this 3.125ns is "lost" at the ADC. In general these are often only a couple of hundred picoseconds - even if it was +/-400ps (which is pretty large) this means you lose 800ps from each data valid window, reducing it to 2.325ns.

The minimum data eye that a Xilinx device can capture statically depends on family and speedgrade, but even more significantly it depends on clocking architecture. Take a look at this post on different input capture clocking architectures. The timing numbers in the specs are not precise, but from experience you can capture interfaces with as little as 1.5ns windows (with some architectures). Even at 2.325ns, a number of architectures will likely work.

So, unless the ADC has bad timing, this interface is likely possible with static capture. But only if you do things right. All of these clocking architectures have requirements on pin placement

  • The bit clock must be on a clock capable pin
  • For some clocking schemes the associated data pins must be in the same bank as the clock pin

Now we get to how to implement it. I don't use the SelectIO Wizard often (or recently), but it can help you build some of the basics of this system, including (if I remember correctly) implementing the required BUFIO/BUFR and IDELAYs. But it is just creating structure - it is up to you to determine which options you want (IDELAY on data only, on clock only, or on both) and if you do use IDELAYs, what values to set the IDELAYs to. So if the SelectIO wizard can help you construct the right architecture, then go for it - it will save a fair amount of typing (instantiating all the components is somewhat tedious).

Once you have a proposed architecture, you need to test it. To do so, you must have accurate constraints for your interface - this is the only way to get the tool to tell you if the interface is good or not. You can refer to these posts on constraining edge aligned and center aligned source synchronous interfaces. The constraints wizard may be able to help you with constructing your constraints.

Once you have the input interface built (or at least "mocked up") and the constraints written, you can perform synthesis on the design and get timing results. Since all the resources involved (the IBUF, the clock buffers, the ISERDES, etc...) are all fixed resources with dedicated routing, you don't actually need to perform place and route to get timing results - synthesis will suffice. Once synthesis is done, you can inspect the timing reports to determine

  • Does the interface pass?
  • If not, can I adjust the IDELAY (or MMCM phase) to make it pass
    • If so, by how much

Then you can make your adjustments, run synthesis again (or in some cases, just regenerate the timing report) and if your interface passes, then you are done.

It can be a lot of work, and it does require some fairly detailed understanding of how the device works, but hopefully these posts will help.

If, after doing all this, the tool says the interface does not pass and cannot be made to pass, you can explore other clocking schemes, or, if none of those will work, then you have to investigate solutions with dynamic calibration.

Avrum

Explorer
Explorer
2,024 Views
Registered: ‎08-21-2013

Re: Can I use SelectIO to read serialized LVDS ADC?

@avrumw,

Alot to absorb, but it's starting to make a bit of sense. I always find IO constraints confusing. 

I should safely be able to capture statically. That has been working on the Altera side. The LTC2271 has about 60 ps of jitter. We're also using a MCP37231-200, but the data sheet does not specify the jitter. In both cases, the traces are very short and well matched. On a scope, the DCLK is centered on the data at the FPGA input. The biggest problem with the MCP37231 is the test pattern does not work (it was their first ADC product).

I'm starting to doubt I can do this using SelectIO. It seems to assume the clock is edge aligned and does not provide any way to use the phase offset of the MMCM (called PLL's on Altera). It only allows using the IDELAY. But the clock may actually be to slow for that to work. As I understand it, there are 32 taps of 78 ps.

I have to say one of the things I will really miss from Altera Quartus is SignalTap II Logic Analyzer. Others have said the best way to use the Vivado Logic Analyzer if via scripting, but SignalTap was vastly simpler and I used it routinely. If I could pick one feature to add to Vivado, that would be it.

Thanks to you and markg@prosensing.com for at least giving me a direction.

 

 

 

 

0 Kudos
Historian
Historian
2,015 Views
Registered: ‎01-23-2009

Re: Can I use SelectIO to read serialized LVDS ADC?

The LTC2271 has about 60 ps of jitter.

Careful - we are not (just) talking about the jitter - we are looking at the window uncertainty. From the table on page 6 we have tDATA; the Data to DCO Delay, which is specified as 0.35*tSER min (and 0.65*tSER max), where tSER is the bit period (so 1/2 of a DCO period). Since you said that you were running at 160MHz (DDR) your tSER is 3.125ns. Since you only (effectively) get 0.35*tSER setup and 0.35*tSER hold, your window is 0.7*tSER, which is 2.1875ns (a little worse than my "worst case" +/-400ps). This is on top of your 60ps of jitter (which should be specified as input jitter on your clock).

At 2.1875ns, timing is tighter - it is probably still doable in mode devices, but your clocking architecture will be critical - it may be too small for some of the global clocking schemes (you may need to use ChipSync clocking to make it work).

And, yes, you can have 32 taps of (approximately) 78ps each, which gives you a maximum delay of 2.5ns. Given that your bit period is 3.125ns, one IDELAY is not enough to span the entire range. However, you do have the option of delaying the clock (which will move you up to 2.5ns in one direction) or delaying the data (which will move you up to 2.5ns the other way) - between the two you will be able to cover the entire range...

Avrum

Scholar drjohnsmith
Scholar
2,013 Views
Registered: ‎07-09-2009

Re: Can I use SelectIO to read serialized LVDS ADC?

A quick answer, yes job is very possible.
Quick look on web, you find plenty of examples of people that have used the LTC2271 and xilinx fpgas
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
1,993 Views
Registered: ‎01-22-2015

Re: Can I use SelectIO to read serialized LVDS ADC?

@corestar

     I'm starting to doubt I can do this using SelectIO.
It seems that the FRAME output  (and others?) of the ADC need to be captured along with the DDR DATA - and I'm not sure this can be done with just one SelectIO.

Mark

0 Kudos
Historian
Historian
1,946 Views
Registered: ‎01-23-2009

Re: Can I use SelectIO to read serialized LVDS ADC?

Just to be clear, we are being a little loose with the term SelectIO...

A "SelectIO" is the name Xilinx gives to the I/O component on their FPGAs; the IBUF, OBUF(T), I/OLOGIC, I/OSERDES, I/ODELAY...

What we are mostly referring to here is the "SelectIO Wizard" that creates an IP core that instantiates the appropriate number of SelectIO components and the associated clocking components to create a small system that can capture/output, deserialize/serialize a number of bits of an interface...

Avrum

Explorer
Explorer
1,884 Views
Registered: ‎08-21-2013

Re: Can I use SelectIO to read serialized LVDS ADC?

markg@prosensing.com,

My worst case is 9 channels (8 data and 1 frame) for the MCP37231. For the  LTC2271 I only need two channels since I use the test patterns for bit slip.

The SelectIO allows me to choose 9 channels, but I need to check that their are enough channels on compatible banks on the FPGA. As near as I can tell, there is exactly one Xilinx FPGA that will work for us (Artix 7 XC7A50T in CPG236 10x10 mm package), so I plan to make a project and see if the tools complain.

Porting a nearly complete project from Altera to Xilinx is proving to be alot of work and probably not the brightest thing I've decided to do. I've been looking at chips and tools, but if the support that you and others have provided is any indication of the value of these forums, that's actually an enormous consideration as well. Intel has basically killed Altera.

Explorer
Explorer
1,873 Views
Registered: ‎08-21-2013

Re: Can I use SelectIO to read serialized LVDS ADC?

@avrumw,

Good point about the MIN and MAX tDATA (I need to focus on one issue at a time). Unfortunately, the MCP37231 does not even give the range (time for a phone call to Microchip). I'm guessing their is a distribution of tDATA values centered on the typical value with smaller numbers as you move to the min/max values (I'm assuming tDATA varies from one chip to another and is constant for a given chip). It may have just been dumb luck that all our prototypes worked fine. I think it's become very clear I will need to implement a state machine optimize the clock offset.

One thing that is not clear is that tDATA is the offset of DCO to data, but apparently all the data channels are aligned with each other (at least coming out of the ADC)? I don't see anything in the datasheet for a variation among them. If so, I guess it must be easier for ADC vendors to align the data channels than to accurately offset the clock?

I had considered the idea of offsetting both the data and clock in order to effectively get twice the delay,  but it looks like the SelectIO has an option to use an external MMCM via "Clocking Strategy : Internal Clock" option (named backwards in my opinion). I could then phase shift the clock that way. I'm not sure which is better and have some research to do. I have a feeling by the time I'm done screwing around with the SelectIO IP I'll find it is just easier to do it with primitives as a number of you have suggested, but I'm hoping it will at least tell me if the design will fit in the FPGA.

I've been having trouble finding an Artix-7 board to try all this out, but it occurred to me the Zynq on my Zedboard has an Artix 7 fabric, so I should be able to try it there.

 

 

0 Kudos
Explorer
Explorer
1,866 Views
Registered: ‎08-21-2013

Re: Can I use SelectIO to read serialized LVDS ADC?

@drjohnsmith,

I have not actually found anything specific to the LTC2271 (any links would be appreciated), but that's probably not critical. I've found several app notes and the feedback I've gotten here has somewhat cleared up my confusion as to why the app notes use the approach they do as opposed to just using SelectIO. I need to actually do it to completely understand things.

0 Kudos
Historian
Historian
1,838 Views
Registered: ‎01-23-2009

Re: Can I use SelectIO to read serialized LVDS ADC?

One thing that is not clear is that tDATA is the offset of DCO to data, but apparently all the data channels are aligned with each other (at least coming out of the ADC)? I don't see anything in the datasheet for a variation among them. If so, I guess it must be easier for ADC vendors to align the data channels than to accurately offset the clock?

So you have to understand how manufacturers specify the timing characteristics of a device. In the case of the LTC2271, they guarantee OUT* will change anywhere from 0.35*tSER to 0.65*tSER before the edge of DCO - this means that at a 160MHz clock, where tSER=3.125ns, the data will change anywhere from 1.09375ns before the edge to 2.03125ns before the edge. Since this the only pertinent characteristic for this interface, this is the only thing they promise.

This means:

  • On any given chip at any given time any one of the outputs may change as late as 1.09375ns before the clock
  • On any given chip at any given time any one of the outputs may change as early as 2.03125ns before the edge of the clock

Since nothing else is promised, nothing else is guaranteed. You may have two outputs of the same chip at the same time that are at opposite extremes. You can have one pin on one particular device that can vary over the entire range over time. While neither of these are likely, and certain physical realities state that the "extremes" are actually impossible, you have to design your interface as if these are true. Again, the manufacturer only promises what I have stated.

Between these two extremes, it is impossible to know if a given data pin is still  holding the old value, has transitioned to the new value, or is somewhere in between - for practical purposes we assume the data between the extremes is "unknown".

The good thing is that this can be translated directly into constraints for your design

 

create_clock -name DCO_clk -period 6.5 [get_ports DCO]

set_input_jitter [get_clocks DCO_clk] 0.6

set_input_delay -clock DCO_clk -min -2.031                  [get_ports {OUT* FR*}]
set_input_delay -clock DCO_clk -max -1.094                  [get_ports {OUT* FR*}]
set_input_delay -clock DCO_clk -min -2.031 -add -clock_fall [get_ports {OUT* FR*}]
set_input_delay -clock DCO_clk -max -1.094 -add -clock_fall [get_ports {OUT* FR*}]

There are other ways of specifying these constraints (and these may not be the easiest to deal with), but they come directly from the spec, so we will go with them for now.

I think it's become very clear I will need to implement a state machine optimize the clock offset.

I know there is a lot to take in, but go back to my original reply. The big question is "can this be captured statically, or does it require dynamic calibration". The goal is always to do static capture - to design a clocking and input structure that has one static configuration that can capture the data in spite of the unknowns given above. From the specification, we know that the data is guaranteed to be static from at least 0.35*tSER (1.09375ns) before the clock edge to at least 0.65*tSER before the next clock edge, (3.125-0.06-0.65*(3.125))=1.03375ns, the total width of the period of time where the data is guaranteed to be valid in spite of all the variation given above is 2.1275ns.  As I said in my earlier e-mail, this should be wide enough for static capture in most architectures with a "good" clock architecture.

I had considered the idea of offsetting both the data and clock in order to effectively get twice the delay,  but it looks like the SelectIO has an option to use an external MMCM via "Clocking Strategy : Internal Clock" option

Now, go back and look at the post on different capture clocking architectures. These two options from the SelectIO Wizard correspond to two different clocking architectures. The one with the MMCM is b) "BUFG Capture with MMCM" and the other one is c) "DIrect Capture with BUFIO or BUFR". As I stated in that post, option c) requires the smallest valid window for most architectures. So moving to option b) makes the timing more difficult to meet (maybe not impossible, but will certainly have less margin).

So looking at option c), we don't need to get "twice the delay". We need to find a static configuration of IDELAYs that move the data window provided by the device into the setup and hold window required by the FPGA using this clock architecture. I don't know exactly what that is, but can (generally) be accomplished two ways:

  • Pushing the clock forward to move the required setup/hold window onto the the data provided window
  • Pushing the data forward to move the provided data window onto the "next" setup/hold required window

Again, we don't know which is better, but with 2.5ns of "push" available, one of these two is guaranteed to be enough delay, since, between them, you can change the relationship by more than 3.125ns (your bit period) - again assuming that the window is wide enough to start with.

So, again, you need to start with an architecture, apply the constraints, and synthesize it. Then, with the data from static timing analysis, you can figure out what delays you need, and adjust those.

As a final note, the constraints above may not be sufficient on their own - in addition to the timing, the constraints define a relationship about "which clock edge" captures "which data window" (remember, you have two clock edges - rising and falling - and two data windows - the one centered around the rising edge and the one centered around the falling edge). With all the weird timing requirements, it is not a given that you want to capture the rising edge window with the rising edge clock, and, in fact, this is not the default behavior of the static timing analysis engine. Therefore, we may need to modify the edge relationships. The information on how to do that is in the posts on constraints, but we can cover that once you get the first static timing analysis results from the tool.

Avrum

Explorer
Explorer
1,299 Views
Registered: ‎08-21-2013

Re: Can I use SelectIO to read serialized LVDS ADC?

I finally got the hardware I need to test this on my Zedboard with an LTC2271. I decided to try the "easy" way first and use the "SelectIO Wizard". Three days later I still could not get the test pattern and frame clock to show up correctly. And yes, I did all the resets etc as per the docs.

I think I see the reason why. When using the "External Clock" mode, the wizard generates the following:

ADC_LVDS_no_delay.jpgSelectIO Wizard using External Clock

However, reading UG471 under ISERDESE2, I found the following:

UG471_ISERDESE2_clocking.jpg

So in this mode, I believe the wizard is doing what UG471 says NOT to do (not sure what they meant by "... were inverted by the designer ..."). CLK and CLKDIV will have different phases (or am I not understanding this). I believe this was causing the Q outputs to be inconsistent. I tried adding various delays to the clock but to no avail.

I found this post:

https://forums.xilinx.com/t5/Timing-Analysis/BUFIO-BUFR-question/td-p/137802

that says the BUFIO and BUFR outputs will be phase aligned (for Virtex 4 at least) , so maybe I'm wrong. But I could not get it to work.

I could set the "SelectIO Wizard"  to "Internal Clock" mode and create the PLL myself, but at that point the Wizard is not really doing much for me.

I just decided to create the primitives myself, as everyone here told me to do in the first place (some of us have to learn the hard way), and it works fine:

 

ADC_LVDS_using_PLL.jpgUsing manual instantiation

I just append two consecutive 8-bit outputs (after bit-slip) to get my 16-bit sample per channel and it seems to work reliably. Based on the incredibly helpful posts of @avrumw , I plan to implement a state machine to dynamically move the bit clock to the center of the data. Probably just dumb luck that the above worked with no phase offset.

This was the big unknown: I guess I'm leaving Altera. I'm sure Intel will be devastated by that loss  :-).

0 Kudos