mikrocontroller.net

Forum: FPGA, VHDL & Co. LVDS Clock at Artix7?.


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Sunny L. (sunny_l)


Bewertung
0 lesenswert
nicht lesenswert
Hello,

I have a 500 MHz oscillator, which is on a clock divider AD9508
connected. From the clock divider several bars go out to ADC, DAC,
but also to the FPGA .

The clock divider is configured for output to the FPGA :
Register 0x27 to 0x2C, in the datasheet
on page 38.
0x27: x "04"
0x28: x "00"
0x29: x "00"
0x2A: x "00"
0x2B: x "14"
0x2C: x "00"
Concrete:
x "04" in register 0x27 is divisor -1. It is divided by 5.
The 500 MHz will become 100 MHz.
The registers 0x28 ... 0x2A make are only continue for divisor and 
phase.
x "14" b "00010100" in register 0x2B says:
Divider 3 power-down: 0
0 = divider 3 is synchronized during output sync (default): 0
These bits determine the phase of the OUT3 driver: 01 = noninverting
These bits determine the OUT3 driver mode: 010 = LVDS 1 × 3.5 mA
(default)
Reserved: 0b = default

This is connected to the Artix7 as LVDS and as in the appendix. 100
Ohm between the lines and then per line 100 nF to the FPGA .
I have that from the ADC data sheet:
Figure 90 Page 33.

In the FPGA I have the following:
In XDC:
## Clock signal Sch name = CLK_AD9508_OUT3
set_property PACKAGE_PIN G4 [get_ports CLK_AD9508_OUT3p]
set_property PACKAGE_PIN F4 [get_ports CLK_AD9508_OUT3n]
set_property IOSTANDARD DIFF_SSTL15 [get_ports CLK_AD9508_OUT3p]
set_property IOSTANDARD DIFF_SSTL15 [get_ports CLK_AD9508_OUT3n]

There is also the first question:
I used DIFF_SSTL15 because I found no LVDS or anything like that
have. What should I use at this point?

In VHDL I have this:
IBUFGDS_inst : IBUFGDS
generic map (
DIFF_TERM => FALSE, -- Differential Termination
IBUF_LOW_PWR => FALSE, -- Low power (TRUE) vs. performance (FALSE) 
setting for referenced I/O standards
IOSTANDARD => "DIFF_SSTL15")
port map (
O => CLK_AD9508_OUT3, -- Clock buffer output
I => CLK_AD9508_OUT3p, -- Diff_p clock buffer input (connect directly to 
top-level port)
IB => CLK_AD9508_OUT3n -- Diff_n clock buffer input (connect directly to 
top-level port)
);

So far, I use the clock in the FPGA only for a counter of an LED
flashes. And there's the problem: sometimes it stops flashing
or has a short break. When I measure the beat with the Oszi, so
Probe to the 100 ohm resistor, then I see beautiful 100 MHz without
Dropouts with an amplitude of almost 500 mV and a DC offset of
about 1.2 V. Otherwise, the voltages also fit, the FPGA gets 1.8 V, 1.0
V and 3.3 V.

Am I doing something grossly wrong? A little rum grinding would not be a 
problem. to
I also configure the clock divider to CMOS and use only one
Lead for the CMOS clock.


thanks
iosman

von Christian R. (supachris)


Bewertung
0 lesenswert
nicht lesenswert
Do you have the 100 Ohm termination resistor at the FPGA side? Which 
VCCIO do you use at the FPGA bank? You have of course to set the IO 
standard to LVDS, this is available in Artix.

von Christoph Z. (christophz)


Bewertung
0 lesenswert
nicht lesenswert
I have a dejavu: Beitrag "LVDS Clock am Artix7"

The conclusion was, that the input of the Xilinx FPGA and the input of 
your ADC are different. You can not apply the ADC application note to 
the FPGA!

In short, the ADC input is self-biasing and therefor you can AC couple 
without additional components. For the FPGA either replace the the 100 
nF capacitor with a 0 Ohm resistor or add a proper biasing network to 
the FPGA input.

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
See page 20 in the AD9508 dats sheet. You have to remove the 100 nF 
capacitors (see fig. 40). If you are using a 2.5V FPGA bank, you can 
also remove the 100 Ohm resistor and activate the FPGA internal 
termination.

note: You have to configure the outputs as LVDS!

: Bearbeitet durch User
von Gustl B. (-gb-)


Bewertung
0 lesenswert
nicht lesenswert
Hello Sunny, i did something absurdly simmilar. And it works great! But 
i am using an Spartan7 and an AD9650 as ADC. Later this day i will post 
some code for configuring the Clockdivider and the Registercontent i 
use.

von Gustl B. (-gb-)


Bewertung
0 lesenswert
nicht lesenswert
So, now i can look at my code:

The Registers:

x"01",x"00",x"00",x"00",x"14",x"00", -- 21 to 26: AD9508 OUT0 to DAC
x"09",x"00",x"00",x"00",x"1E",x"A0", -- 27 to 32: AD9508 OUT1 
unused/disabled
x"13",x"00",x"00",x"00",x"14",x"00", -- 33 to 38: AD9508 OUT2 to ADC
x"13",x"00",x"00",x"00",x"14",x"00", -- 39 to 44: AD9508 OUT3 to FPGA


So ... i disabled OUT1 because it is unused. Divide by 2 gives 250 MHz 
to the AD9747 DAC, for the FPGA and the ADC i use divide by 20 for 25 
MHz.

To configure the Clockdivider AD9508 i use a carefully crafted el'cheapo 
SPIish interface:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity AD9508_SPI is Port(
  clk: in std_logic;
  start: in std_logic;
  data: in std_logic_vector(8*6*4-1 downto 0);
  SCLK: out std_logic;
  SDIO: out std_logic;
  SDO: in std_logic;
  nCS: out std_logic;
  nRESET: out std_logic;
  nSYNC: out std_logic);
end AD9508_SPI;

architecture Behavioral of AD9508_SPI is

type s_control_type is(s_wait, s_init, s_send_conf);
signal s_control: s_control_type:= s_wait;
signal INIT: std_logic:='0';
signal INSTHEADER: std_logic_vector(15 downto 0):=x"602C";
signal SENDREG: std_logic_vector(0 to 16+8*6*4-1):=(others => '0');
signal counter: unsigned(10 downto 0):=(others => '0');
signal waitcounter: unsigned(19 downto 0):=(others => '0');
signal adr: integer range 0 to 207:=0;

begin

nRESET <= '1';
nSYNC <= '1';
process begin
  wait until rising_edge(clk);
  if    s_control = s_wait then
    waitcounter <= waitcounter +1;
    if (INIT = '0' and waitcounter = 2**10) or (start = '1' and INIT = '1') then
      counter <= (others => '0');
      SENDREG <= INSTHEADER & data;
      s_control <= s_send_conf;
    end if;
  elsif s_control = s_send_conf then
    if counter < 1663 then
      counter <= counter +1;
    end if;
    if counter = 1663 then
      s_control <= s_wait;
      INIT <= '1';
    end if;
  end if;
end process;
adr <= to_integer(counter(10 downto 3));
SDIO <= SENDREG(adr);
SCLK <= counter(2) when counter < 1663 else '1';
nCS <= '0' when s_control = s_send_conf else '1';

end Behavioral;

clk: in std_logic; that is a 100 MHz Clock in the FPGA
start: in std_logic; is a start signal, it starts the SPI action
data: in std_logic_vector(8*6*4-1 downto 0); are the 6*4 Bytes, 
Registers 21 to 44.

### Schematic ###
The ADC Clock input is self biased at the ADC I use. But i don't know 
which ADC you are using, so it may depend.
The FPGA Inputs are not biased internally. But the AD9508 delivers a 
LVDS Signal with a nice DC offset. So just connect it to the FPGA 
without capacitors.

I use an external 100 Ohm Termination becaus i supply the FPGA Bank with 
1.8 V, so i can not use the internal Termination. [citation needed *]

In my VHDL i use:
IBUFGDS_inst : IBUFGDS
generic map (
DIFF_TERM => FALSE, -- Differential Termination
IBUF_LOW_PWR => FALSE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "LVDS_25")
port map (
O => CLK_AD9508_OUT3, -- Clock buffer output
I => CLK_AD9508_OUT3p, -- Diff_p clock buffer input (connect directly to top-level port)
IB => CLK_AD9508_OUT3n -- Diff_n clock buffer input (connect directly to top-level port)
);

And in the .xdc File:
set_property PACKAGE_PIN G4 [get_ports CLK_AD9508_OUT3p]
set_property PACKAGE_PIN F4 [get_ports CLK_AD9508_OUT3n]
set_property IOSTANDARD LVDS_25 [get_ports CLK_AD9508_OUT3p]
set_property IOSTANDARD LVDS_25 [get_ports CLK_AD9508_OUT3n]

* https://www.xilinx.com/support/answers/43989.html there are two flow 
charts, one (the upper) for the HP Banks, and one, the lower, for the HR 
banks. I use an HR Bank at the Spartan7 with 1.8 V. So i cannot use the 
internal Termination. So if you use an HR bank you either must supply 
2.5 V or use external termination.

: Bearbeitet durch User
von Sunny L. (sunny_l)


Bewertung
0 lesenswert
nicht lesenswert
Sunny L. schrieb:
> Hello,
>
> I have a 500 MHz oscillator, which is on a clock divider AD9508
> connected. From the clock divider several bars go out to ADC, DAC,
> set_property PACKAGE_PIN F4 [get_ports CLK_AD9508_OUT3n]
> or has a short break. When I measure the beat with the Oszi, so
> Probe to the 100 ohm resistor, then I see beautiful 100 MHz without
> https://engineoilforbikes.com https://bestcordlessvacuumx.com
> Dropouts with an amplitude of almost 500 mV and a DC offset of
> about 1.2 V. Otherwise, the voltages also fit, the FPGA gets 1.8 V, 1.0
> V and 3.3 V.

> thanks
> iosman

thanks for the information.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.