FPGARelated.com
Forums

Virtex-4 ISERDES and ADS527X ADCs

Started by Sean Durkin January 27, 2006
Hi *,

I'm having a litte problem trying to understand some things regarding
the ISERDES in Virtex-4-IOs.

Here's what I want to do:

We use a lot of ADS527X-ADCs from TI. Those parts output 12bit/sample
via LVDS-DDR-links running at up to 480Mbit/s. Up to now, using Virtex-2
Pro, getting this into the FPGA is a little tricky (see xapp774). In
short, the current way is to feed the serial data into two carefully
hand-placed 6-bit-shift-registers that are clocked with 180-degrees
shifted clocks, and read those shift registers out in parallel once all
12 bits have arrived. Takes quite a bit of hand-placement, you have to
be careful which I/Os you use to connect the clocks and data, you need
DCMs to do phase-shifting, etc. Kinf of tricky, but it works.

Now we're about to switch to Virtex-4, and at first glance the ISERDES
seems like the perfect thing to make it all easier. But the more I think
about it the more problems arise.

First, since all signals coming from the ADCs are differential signals,
I need to instantiate an IBUFDS for each one. Plus I need to assign the
LVDS_25-IOSTANDARD-attribute to it, as well as the DIFFTM-attribute,
since there are usually no external termination resistors on the board
to save space.

The signal I get as output from the IBUFDS I can feed into an ISERDES.
Since one ISERDES can only give me 6 bits in parallel, I need to use two
ISERDES in Master-/Slave-mode, but then they can only give me 10bits
instead of the 12 I actually get from the ADCs. So it's not going to
work that way.

Someone here posted awhile back that they would simply feed the
_n-signal in one ISERDES, the _p in another, and have them run at clocks
shifted by 180 degrees. That way, each ISERDES would give me one
6-bit-nibble of my 12-bit data word, one the "even" bits, one the "odd"
bits of my data word. Sounds pretty easy to do.

But that would mean using the two signals from a differential pair as
two separate single-ended signals. Kinda misses the whole point of using
differential signaling in the first place...

The way I see it there are several problems with this approach:

1. If I don't use an IBUFDS for the differential input signal, I can't
turn on the differential termination, plus I can't set the I/O-standard
to LVDS_25 (the tools simply ignore those settings for single-ended
I/Os). Again, kind of takes away the advantage of using LVDS in the
first place. If I do instantiate an IBUFDS to at least get termination
and set the IO-standard, I can't access the _n and _p-signals to supply
two separate ISERDES anymore, and I can't feed the IBUFDS-output-signal
to two separate ISERDES either.

2. If I use the two signals of a differential pair as two separate
single-ended signals, what I/O standard do I assign to them? It would
have to be something that can cope with the tiny little swing of an
LVDS-signal. Looking at the datasheet, each line of a differential pair
has a worst-case V(high) = 1.265V and V(low) = 1.140V, so I'd have to
use LVCMOS_15 or something like that and pray that this works.

3. To control the ADCs (reset, powerdown, serial interface for enabling
test-modes etc.), I need an I/O-voltage of 3.3V. Normally it is not a
problem to use LVDS_25-INPUTS in a bank that otherwise uses 3.3V-I/Os,
since the differential input buffers are powered by Vccaux, which is
availabe in all banks (at least that's how it is in Virtex2 Pro).
But if I have to use e.g. LVCMOS_15 for the LVDS-inputs, I need to power
the entire bank with 1.5V. Not only would that mean I need to supply yet
ANOTHER voltage on the board (one that I wouldn't need otherwise), but
it would also mean I'd waste most of an entire bank of I/Os I could've
otherwise used to control the ADCs and do some other little things. I/Os
are precious as well as the board space I'd need for an additional
regulator.

So I'm not really comfortable with this approach...

The way I see it the only way to do it "properly" is doing it the way it
was done in xapp774, which will take some effort "porting" it to Virtex-4.

Is there some more "elegant" way to do it? I'd hate to just not use the
ISERDES, those things are way to kewl to waste... :)

Any suggestions?

cu,
Sean
Sean Durkin wrote:
> We use a lot of ADS527X-ADCs from TI. Those parts output 12bit/sample > via LVDS-DDR-links running at up to 480Mbit/s. Up to now, using Virtex-2 > Pro, getting this into the FPGA is a little tricky (see xapp774). In > short, the current way is to feed the serial data into two carefully > hand-placed 6-bit-shift-registers that are clocked with 180-degrees > shifted clocks, and read those shift registers out in parallel once all > 12 bits have arrived. Takes quite a bit of hand-placement, you have to > be careful which I/Os you use to connect the clocks and data, you need > DCMs to do phase-shifting, etc. Kinf of tricky, but it works.
(posted without having looked at the ADS datasheet or V4 IO clocking) I've sucessfully done this sort of thing in V2-ish parts using one of the nifty _DIFF_OUT buffers ( or hand built equivalent) to create complementary local clocks to the DDR IOB registers (XAPP609), with the next CLB register stage constrained only by a MAX_DELAY, and the DCM clocks only used for the half rate logic. This makes it fairly easy to hit IOB DDR timing without needing any funky DCM phase shift delay calibration logic, only LOC's on the I/Os to the proper local clocking region. At 480 Mbps, I'd advise sticking with LVDS & DT terminators. have fun, Brian
"Brian Davis" <brimdavis@aol.com> wrote in message 
news:1138387310.365316.257760@z14g2000cwz.googlegroups.com...
> Sean Durkin wrote: >> We use a lot of ADS527X-ADCs from TI. Those parts output 12bit/sample >> via LVDS-DDR-links running at up to 480Mbit/s. Up to now, using Virtex-2 >> Pro, getting this into the FPGA is a little tricky (see xapp774). In >> short, the current way is to feed the serial data into two carefully >> hand-placed 6-bit-shift-registers that are clocked with 180-degrees >> shifted clocks, and read those shift registers out in parallel once all >> 12 bits have arrived. Takes quite a bit of hand-placement, you have to >> be careful which I/Os you use to connect the clocks and data, you need >> DCMs to do phase-shifting, etc. Kinf of tricky, but it works. > > (posted without having looked at the ADS datasheet or V4 IO clocking) > > I've sucessfully done this sort of thing in V2-ish parts using one > of the nifty _DIFF_OUT buffers ( or hand built equivalent) to create > complementary local clocks to the DDR IOB registers (XAPP609), > with the next CLB register stage constrained only by a MAX_DELAY, > and the DCM clocks only used for the half rate logic. > > This makes it fairly easy to hit IOB DDR timing without needing > any funky DCM phase shift delay calibration logic, only LOC's on > the I/Os to the proper local clocking region. > > At 480 Mbps, I'd advise sticking with LVDS & DT terminators. > > have fun, > Brian >
Guys, It's Friday night and I hear the siren call of the pub, so excuse the briefness of this answer! I've also had great success with DDR links without resorting to DCM phase shift complexity. Check out XAPP233 figs. 9 and 10. The key insight is to use a latch (NOT a FF) to align the clock enables in the rising and falling edge clock domains. The latches are fast enough to meet the timing way beyond 480M, my stuff is working great at 622M. Agree totally with Brian's recommendation re. LVDS_DT. HTH, Syms.
Brian -

I don't see any documentation on the DIFF_OUT buffers you mention.

Do you have any info on them or pointers to doc?

Thanks!

John Providenza

johnp wrote:
> > I don't see any documentation on the DIFF_OUT buffers you mention. > Do you have any info on them or pointers to doc? >
All the V2-ish differential input buffers have a complementary output available, that can be used to create a 180 degree clock without needing a DCM. These can also be used just to invert a differential input without needing any other logic (or board cuts & jumps). Look at the DIFFS component in fpga_editor to see what's going on; besides the normal 'phantom' route from the DIFFS to the DIFFM, there's also a route from the DIFFM to a differential receiver in the DIFFS that outputs the complement signal. I first spotted these when they showed up in early versions of XAPP622 as a hard macro. Support & tool bugs for these have varied version to version, see Answer Record 21958 for recent problems. I've banged into various other problems in using them over the years; if I get a chance this weekend, I'll try to dig up some old webcase code showing how to create one out of two normal IBUF{G}DS's as a work around. These can be used on regular IOB inputs as well as global clock inputs, but you've generally needed to LOC the global input buffer and bufg's to allowed sites to get this to work. search for ibufgds_diff_out ibufds_diff_out Brian
Sean Durkin schrieb:

> The signal I get as output from the IBUFDS I can feed into an ISERDES. > Since one ISERDES can only give me 6 bits in parallel, I need to use two > ISERDES in Master-/Slave-mode, but then they can only give me 10bits > instead of the 12 I actually get from the ADCs. So it's not going to > work that way.
Why? An ethernet frame is hundreds of bits and you can still receive it with an ISERDES. Use a 1:6 serdes and continue to process your data stream in chunks of 6-bit at a convenient rate of 80 MHz. You can add logic in the FPGA-fabric that immediately converts the stream to 12-bits at 40MHz. But probably you get a smaller circuit when you do all your signal processing 6-bit-nibble serial at 80MHz. This issue came up in this newsgroup a few times before. Somehow everybody immediatly recognizes that a 16-bit entity can be split up into two bytes of 8-bits. But as soon as the numbers change a little apparently it becomes less obvious. Kolja Sulimma
Sean Durkin wrote:
> > The signal I get as output from the IBUFDS I can feed into an ISERDES. > Since one ISERDES can only give me 6 bits in parallel, I need to use two > ISERDES in Master-/Slave-mode, but then they can only give me 10bits > instead of the 12 I actually get from the ADCs. So it's not going to > work that way. >
Use the ISERDES setup you describe here to get 6 bits at a time. Really quick pseudo code for a solution: signal left : std_logic_vector ( 5 downto 0); signal sample : std_logic_vector ( 11 downto 0); if ( falling_edge( sample_clock ) ) then left <= ISERDES_out(5 downto 0); end if; if ( rising_edge( sample_clock ) ) then sample <= left && ISERDES_out(5 downto 0); end if; Sample clock needs to be properly phased to the ISERDES output, and a timing constraint with 1/2 the period of sample_clock is placed between ISERDES_out and the two destination registers. The tools will take it from here. Regards, Erik. --- Erik Widding President Birger Engineering, Inc. (mail) 100 Boylston St #1070; Boston, MA 02116 (voice) 617.695.9233 (fax) 617.695.9234 (web) http://www.birger.com
Symon wrote:
>The key insight is to use a latch (NOT a FF) to align the clock enables >in the rising and falling edge clock domains. The latches are fast enough >to meet the timing way beyond 480M, my stuff is working great at 622M.
Alas, I swore off Xilinx latches after the Great Latch Inversion of '00 Brian p.s. Actually, it's not the actual latches I distrust; it's the software guys configuring the latches, having to interpret the latch enable sense when it's not properly documented in the datasheet. GoogleGroups "CLB latch clock inversion" from latch_bug1.txt: : For an active low latch in an EDIF input file, you get : the following results when tracing the clock signal through : the tool flow: : : tool stage XC4000EX derived Virtex Derived : ------------------------------------------------------- : EDIF in active low active low : MAP out CLK:CLKNOT CLK:CLK : EPIC display dot clock normal clock : SIMPRIM model X_INV -> X_LATCH X_INV -> X_LATCH : real HW transparent low transparent low : : note: X_LATCH SIMPRIM models are transparent high
Kolja Sulimma schrieb:
> Why? An ethernet frame is hundreds of bits and you can still receive it > with an ISERDES.
> Use a 1:6 serdes and continue to process your data stream in chunks of > 6-bit at a convenient rate of 80 MHz. You can add logic in the > FPGA-fabric that immediately converts the stream to 12-bits at 40MHz. > But probably you get a smaller circuit when you do all your signal > processing 6-bit-nibble serial at 80MHz.
> This issue came up in this newsgroup a few times before. Somehow > everybody immediatly recognizes that a 16-bit entity can be split up > into two bytes of 8-bits. But as soon as the numbers change a little > apparently it becomes less obvious.
That's not the problem. The thing is that the ADC sends out, along with the data, a fast clock and a 6x slower clock. If you run the ADC at 70MHz, it sends back a 420MHz clock and a 70MHz clock. The whole thing is designed so you use the 420MHz to clock some sort of deserializing-circuit and the 70MHz to clock out the parallel data and do your processing. So that's the "intended" way to handle this, and of course you'd first look for a way to do it with what you're provided with. Now, since one single ISERDES doesn't handle DDR, it would have to be run at 840MHz, plus I'd need to waste a DCM to double the clock (can they even get up to 840MHz?) I get from the ADC. No way. Alternatively, I could use two ISERDES in Master-/Slave-Mode (then they can handle DDR) to output two 6bit-nibbles, as you suggested. But to get these out, I'd have to have a 140MHz clock, which I don't have. Again, waste a DCM to generate it. And since I normally have 4 of those ADCs hooked up to one FPGA, that's 4 DCMs gone already, in addition to the 4 I need to do phase-shifting anyway. That's 8 total, which is probably every single one available in the devices I have available. Again, no way. The whole point of using the ISERDES in the first place is to save on DCMs, clock nets and hand-placed components, to make do with what is readily available. I still don't see where the ISERDES would make anything easier. cu, Sean
Brian Davis wrote:
> I've sucessfully done this sort of thing in V2-ish parts using one > of the nifty _DIFF_OUT buffers ( or hand built equivalent) to create > complementary local clocks to the DDR IOB registers (XAPP609), > with the next CLB register stage constrained only by a MAX_DELAY, > and the DCM clocks only used for the half rate logic.
First of all, typo in the original posting: it's 840MBps, not 480Mbps I have to deal with. Then on to your suggestion: Sounds good, but the half-rate logic would still be running at 210MHz in my case. I need more deserializing, need to make it slower :) The thing is that the ADC sends out a 420MHz clock and a 70Mhz clock along with the data. So obviously this is designed so that you run some deserializing circuit with the 420MHz, and clock out the parallel data with the 70MHz clock. Plus, you'd do the rest of the processing in the FPGA with the 70MHz, which is easily handled.
> This makes it fairly easy to hit IOB DDR timing without needing > any funky DCM phase shift delay calibration logic, only LOC's on > the I/Os to the proper local clocking region.
The latter is the biggst constraint. In the first board we did, the clocks weren't connected to the local clocking pins. But even if they were, at 840Mbps (sorry, typo in the original posting, it's 840, not 480!), I still needed to do some calibration in every case. At these speeds you're already getting problems if the traces on the board aren't closely matched. I could never get it to work reliably (i.e. considering temperature drift etc.) without phase-shifting and re-calibration from time to time.
> At 480 Mbps, I'd advise sticking with LVDS & DT terminators.
That's what I thought. cu, Sean