Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

using lvds

G´day !!

I´m using an ADC with differential output (LVDS). It´s a device including 8 ADCs with Serial LVDS output. Data from each ADC is serialized and provided on a seperate channel. This serial data (data rate for each serial stream is 700Mbps maximum) is read with Cyclon III. What´s the best way to do this ? I found the ALTLVDS Megafunction, but i think this block has no sense, cause of the serialization factor of 1 for each channel used in my system. But what´s the best way to read and process the sampled input data ??

Is it possible to wire this LVDS Serial data direct to a PIO ???

hope someone can help me

greets !!!

45 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    AD9252 is basically similar to AD9222, expect for a resolution of 14 versus 12 bit.

    I completely agree with josyb about the suggested solution (DDIO + shift register). Also the deserialization factor of 14 is correct. Strictly spoken, you won't necessarily need a PLL for the receiver, because the ADC provide both fast and slow (respectively bit and frame) clock. but, 700 Mbps is pretty on the edge, a means to adjust the clock phases manually may turn out to be badly required. A receiver PLL would use the frame clock (FCO) as input clock and generate the fast clock. You can also connect both ADC clocks to the FPGA and keep all options.

    See below a VHDL example of 4-channel 14-Bit ADC receiver, that can be easily changed to 8 Channels.

    chan:
    FOR I IN 0 TO 3 GENERATE
    	lvds_rcv : altddio_in
    	GENERIC MAP (
    		intended_device_family => "Cyclone III",
    		invert_input_clocks => "ON",
    		lpm_type => "altddio_in",
    		power_up_high => "OFF",
    		width => 1
    	)
    	PORT MAP (
    		datain => AD9259_D(I DOWNTO I),
    		inclock => fastclock,
    		dataout_h => dataout_h(I DOWNTO I),
    		dataout_l => dataout_l(I DOWNTO I)
    	);
    	PROCESS (fastclock)
    	BEGIN
          IF rising_edge(fastclock) THEN
             lvds_sr(I) <= lvds_sr(I)(11 downto 0) & dataout_l(I) & dataout_h(I);
    		END IF;
    	END PROCESS;
    	PROCESS (slowclock)
    	BEGIN
    	   IF reset = '1' THEN
    	      lvds_rx(I) <= (others => '0');
          ELSIF rising_edge(slowclock) THEN
             lvds_rx(I) <= lvds_sr(I);
    		END IF;
    	END PROCESS;
    END GENERATE;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi there !!!

    Are u sure about the value of the serialisation factor? I thought that a serialisationfactor unequal one is only possible if i would mix, say 2 channels, together and transfer the data alternating. so for mixing 2 channels gives an serialisationfactor or deserialisationfactor of 2, so every second bit (beginning with bit 0) belongs to channel 1 and all other to channel 2. So it doesn´t matter how many bits belong to one datastream or sampled value. I´m not sure about but i thought that i found this out while reading through altlvds documentation.

    The problem with running out of PLL came also to my mind as i will use more devices so i think i´ll have to find ways to work without the megafunction and use the dataclock and frame-indicator in combination with shiftregisters...

    So the solution u provided in your previous post is this possible solution using altlvds or not ? what´s this ddr-in block ? Is it possible to go in shiftregisters with differential signals ??

    thanks for helping

    greets
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The serialisation factor in your system is actually 14. The ALTLVDS does not support this, but you could set it to handle a deserialisation of 7 bits and concatenate two 7-bit packets into one 14 bit. ALTLVDS however uses a PLL to sample the inputs, so if you have multiple devices, ADCs in this case) you may run out of PLLs.

    However as the outputs of the ADC are nicely source synchronous and are accompanied by a dataclock and a frame-indicator , you can easily deserialise the ADC data channels with simple shiftregisters. Feed the inputs into a DDR-In block and then serialise the 2 bits in a 7-bit shiftregister each. assemble the 2 7-bit buses into a 14-bit bus and define the right moment to register it.

    You need to do some work to constrain all this though.

    I have done this for ADS527x and AD9222 octal ADCs, unfortunately my code is in AHDL (I do use VHDL nowadays).