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:
1 | library IEEE;
|
2 | use IEEE.STD_LOGIC_1164.ALL;
|
3 | use IEEE.NUMERIC_STD.ALL;
|
4 |
|
5 | entity AD9508_SPI is Port(
|
6 | clk: in std_logic;
|
7 | start: in std_logic;
|
8 | data: in std_logic_vector(8*6*4-1 downto 0);
|
9 | SCLK: out std_logic;
|
10 | SDIO: out std_logic;
|
11 | SDO: in std_logic;
|
12 | nCS: out std_logic;
|
13 | nRESET: out std_logic;
|
14 | nSYNC: out std_logic);
|
15 | end AD9508_SPI;
|
16 |
|
17 | architecture Behavioral of AD9508_SPI is
|
18 |
|
19 | type s_control_type is(s_wait, s_init, s_send_conf);
|
20 | signal s_control: s_control_type:= s_wait;
|
21 | signal INIT: std_logic:='0';
|
22 | signal INSTHEADER: std_logic_vector(15 downto 0):=x"602C";
|
23 | signal SENDREG: std_logic_vector(0 to 16+8*6*4-1):=(others => '0');
|
24 | signal counter: unsigned(10 downto 0):=(others => '0');
|
25 | signal waitcounter: unsigned(19 downto 0):=(others => '0');
|
26 | signal adr: integer range 0 to 207:=0;
|
27 |
|
28 | begin
|
29 |
|
30 | nRESET <= '1';
|
31 | nSYNC <= '1';
|
32 | process begin
|
33 | wait until rising_edge(clk);
|
34 | if s_control = s_wait then
|
35 | waitcounter <= waitcounter +1;
|
36 | if (INIT = '0' and waitcounter = 2**10) or (start = '1' and INIT = '1') then
|
37 | counter <= (others => '0');
|
38 | SENDREG <= INSTHEADER & data;
|
39 | s_control <= s_send_conf;
|
40 | end if;
|
41 | elsif s_control = s_send_conf then
|
42 | if counter < 1663 then
|
43 | counter <= counter +1;
|
44 | end if;
|
45 | if counter = 1663 then
|
46 | s_control <= s_wait;
|
47 | INIT <= '1';
|
48 | end if;
|
49 | end if;
|
50 | end process;
|
51 | adr <= to_integer(counter(10 downto 3));
|
52 | SDIO <= SENDREG(adr);
|
53 | SCLK <= counter(2) when counter < 1663 else '1';
|
54 | nCS <= '0' when s_control = s_send_conf else '1';
|
55 |
|
56 | 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:
1 | IBUFGDS_inst : IBUFGDS
|
2 | generic map (
|
3 | DIFF_TERM => FALSE, -- Differential Termination
|
4 | IBUF_LOW_PWR => FALSE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
|
5 | IOSTANDARD => "LVDS_25")
|
6 | port map (
|
7 | O => CLK_AD9508_OUT3, -- Clock buffer output
|
8 | I => CLK_AD9508_OUT3p, -- Diff_p clock buffer input (connect directly to top-level port)
|
9 | IB => CLK_AD9508_OUT3n -- Diff_n clock buffer input (connect directly to top-level port)
|
10 | );
|
And in the .xdc File:
1 | set_property PACKAGE_PIN G4 [get_ports CLK_AD9508_OUT3p]
|
2 | set_property PACKAGE_PIN F4 [get_ports CLK_AD9508_OUT3n]
|
3 | set_property IOSTANDARD LVDS_25 [get_ports CLK_AD9508_OUT3p]
|
4 | 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.