реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Использование ISERDES2
ZZZRF413
сообщение Jan 13 2015, 13:09
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 26-07-09
Из: Нижний Новгород
Пользователь №: 51 578



Всем доброго дня!
Посоветуйте пожалуйста по следующему вопросу. Есть плата с Xilinx Spartan-6 FPGA (XC6SLX100T-3FGG676C). Необходимо записать данные с АЦП (AD9434) в ОЗУ (тип DDR2). АЦП работает на частоте порядка 400 МГц. Тактовые частоты для ПЛИС и АЦП формируются с помощью микросхемы AD9518. Я хочу задействовать ISERDES2, для того чтобы в ПЛИС работать на меньшей частоте, но к сожалению пока не очень получается.
Я делал как ug382 разными способами и через BUFIO2 и через PLL_BASE, но на этапе MAP вылетает ошибка (см. приложение). Через IP тоже не работает, также вылетает ошибка. Часть электрической схемы платы так же в приложении. Собственно вопрос в чем причина ошибки и как её можно исправить?

Код:
Формирование тактового сигнала
CODE
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 08:29:32 01/13/2015
-- Design Name:
-- Module Name: CLK_Module - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity CLOCK is
Port ( clk0_p : in STD_LOGIC;
clk0_n : in STD_LOGIC;
clk_in : in STD_LOGIC;
clk_out : out STD_LOGIC;
clk0_out : out STD_LOGIC;
dclk0_out : out STD_LOGIC;
SerDes_Strobe : out STD_LOGIC;
SerDes_CLK : out STD_LOGIC);
end CLOCK;

architecture Behavioral of CLOCK is

attribute IOSTANDARD : string;
attribute DIFF_TERM : string;
attribute IBUF_DELAY_VALUE : string;
attribute IFD_DELAY_VALUE : string;
attribute DIVIDE : string;
attribute DIVIDE_BYPASS : string;
attribute I_INVERT : string;
attribute USE_DOUBLER : string;
attribute ENABLE_SYNC : string;
attribute COMPENSATION : string;
attribute BANDWIDTH : string;
attribute CLKOUT0_DIVIDE : string;
attribute CLKOUT0_PHASE : string;
attribute CLKOUT0_DUTY_CYCLE : string;
attribute CLKOUT1_DIVIDE : string;
attribute CLKOUT1_PHASE : string;
attribute CLKOUT1_DUTY_CYCLE : string;
attribute CLKOUT2_DIVIDE : string;
attribute CLKOUT2_PHASE : string;
attribute CLKOUT2_DUTY_CYCLE : string;
attribute CLKOUT3_DIVIDE : string;
attribute CLKOUT3_PHASE : string;
attribute CLKOUT3_DUTY_CYCLE : string;
attribute CLKOUT4_DIVIDE : string;
attribute CLKOUT4_PHASE : string;
attribute CLKOUT4_DUTY_CYCLE : string;
attribute CLKOUT5_DIVIDE : string;
attribute CLKOUT5_PHASE : string;
attribute CLKOUT5_DUTY_CYCLE : string;
attribute CLKFBOUT_MULT : string;
attribute DIVCLK_DIVIDE : string;
attribute CLKFBOUT_PHASE : string;
attribute REF_JITTER : string;
attribute CLKIN_PERIOD : string;
attribute CLK_FEEDBACK : string;
attribute RESET_ON_LOSS_OF_LOCK : string;
attribute BOX_TYPE : string;

component IBUFGDS
-- synopsys translate_off
generic( DIFF_TERM : boolean := FALSE);
-- synopsys translate_on
port ( I : in std_logic;
IB : in std_logic;
O : out std_logic);
end component;
attribute IOSTANDARD of IBUFGDS : component is "DEFAULT";
-- attribute IOSTANDARD of IBUFGDS : component is "LVPECL_33";
attribute DIFF_TERM of IBUFGDS : component is "FALSE";
attribute IBUF_DELAY_VALUE of IBUFGDS : component is "0";
attribute BOX_TYPE of IBUFGDS : component is "BLACK_BOX";

component BUFIO2
port ( I : in std_logic;
IOCLK : out std_logic;
DIVCLK : out std_logic;
SERDESSTROBE : out std_logic);
end component;
attribute DIVIDE of BUFIO2 : component is "4";
attribute DIVIDE_BYPASS of BUFIO2 : component is "FALSE";
attribute I_INVERT of BUFIO2 : component is "FALSE";
attribute USE_DOUBLER of BUFIO2 : component is "FALSE";
attribute BOX_TYPE of BUFIO2 : component is "BLACK_BOX";

component BUFG
port (I : in std_logic;
O : out std_logic);
end component;
attribute BOX_TYPE of BUFG : component is "BLACK_BOX";

component BUFPLL
port (
PLLIN : in std_logic;
GCLK : in std_logic;
LOCKED : in std_logic;
IOCLK : out std_logic;
SERDESSTROBE : out std_logic;
LOCK : out std_logic
);
end component;

attribute DIVIDE of BUFPLL : component is "4";
attribute ENABLE_SYNC of BUFPLL : component is "TRUE";
attribute BOX_TYPE of BUFPLL : component is "BLACK_BOX";
component PLL_BASE
port (
CLKIN : in std_logic;
CLKFBIN : in std_logic;
RST : in std_logic;
CLKOUT0 : out std_logic;
CLKOUT1 : out std_logic;
CLKOUT2 : out std_logic;
CLKOUT3 : out std_logic;
CLKOUT4 : out std_logic;
CLKOUT5 : out std_logic;
CLKFBOUT : out std_logic;
LOCKED : out std_logic
);
end component;
attribute COMPENSATION of PLL_BASE : component is "SYSTEM_SYNCHRONOUS";
attribute BANDWIDTH of PLL_BASE : component is "OPTIMIZED";
attribute CLKOUT0_DIVIDE of PLL_BASE : component is "1";
attribute CLKOUT0_PHASE of PLL_BASE : component is "0.0";
attribute CLKOUT0_DUTY_CYCLE of PLL_BASE : component is "0.5";
attribute CLKOUT1_DIVIDE of PLL_BASE : component is "4";
attribute CLKOUT1_PHASE of PLL_BASE : component is "0.0";
attribute CLKOUT1_DUTY_CYCLE of PLL_BASE : component is "0.5";
attribute CLKOUT2_DIVIDE of PLL_BASE : component is "1";
attribute CLKOUT2_PHASE of PLL_BASE : component is "0.0";
attribute CLKOUT2_DUTY_CYCLE of PLL_BASE : component is "0.5";
attribute CLKOUT3_DIVIDE of PLL_BASE : component is "1";
attribute CLKOUT3_PHASE of PLL_BASE : component is "0.0";
attribute CLKOUT3_DUTY_CYCLE of PLL_BASE : component is "0.5";
attribute CLKOUT4_DIVIDE of PLL_BASE : component is "1";
attribute CLKOUT4_PHASE of PLL_BASE : component is "0.0";
attribute CLKOUT4_DUTY_CYCLE of PLL_BASE : component is "0.5";
attribute CLKOUT5_DIVIDE of PLL_BASE : component is "1";
attribute CLKOUT5_PHASE of PLL_BASE : component is "0.0";
attribute CLKOUT5_DUTY_CYCLE of PLL_BASE : component is "0.5";
attribute CLKFBOUT_MULT of PLL_BASE : component is "1";
attribute CLKFBOUT_PHASE of PLL_BASE : component is "0.0";
attribute DIVCLK_DIVIDE of PLL_BASE : component is "1";
attribute REF_JITTER of PLL_BASE : component is "0.1";
attribute CLKIN_PERIOD of PLL_BASE : component is "2.5";
attribute RESET_ON_LOSS_OF_LOCK of PLL_BASE : component is "FALSE";
attribute BOX_TYPE of PLL_BASE : component is "BLACK_BOX";

component BUFIO2FB
-- synopsys translate_off
generic( DIVIDE_BYPASS : boolean := TRUE);
-- synopsys translate_on
port ( I : in std_logic;
O : out std_logic);
end component;
attribute DIVIDE_BYPASS of BUFIO2FB : component is "TRUE";
attribute BOX_TYPE of BUFIO2FB : component is "BLACK_BOX";

signal clk0_pll:std_logic:='0';
signal clk0:std_logic:='0';
signal clk0fb:std_logic:='0';
signal dclk0:std_logic:='0';
signal LOCKED:std_logic:='0';
signal clk0_out0:std_logic:='0';
signal clk0_out1:std_logic:='0';
signal SD_CLK:std_logic:='0';

begin

CLK0_DIFF_BUF : IBUFGDS
port map( I => clk0_p,
IB => clk0_n,
O => clk0);

CLK_BUF : BUFG
port map( I => clk_in,
O => clk_out);
--CLK0_BUFIO2: BUFIO2
-- port map ( I => clk0,
-- IOCLK => SerDes_CLK,
-- DIVCLK => dclk0,
-- SERDESSTROBE => SerDes_Strobe
-- );
CLK0_BUFIO2: BUFIO2
port map ( I => clk0,
IOCLK => open,
DIVCLK => clk0_pll,
SERDESSTROBE => open
);
CLK0PLL:PLL_BASE
port map ( CLKIN => clk0_pll,
CLKFBIN => clk0fb,
RST => '0',
CLKOUT0 => clk0_out0,
CLKOUT1 => clk0_out1,
CLKOUT2 => open,
CLKOUT3 => open,
CLKOUT4 => open,
CLKOUT5 => open,
CLKFBOUT => open,
LOCKED => LOCKED
);
CLK0_BUFFPLL:BUFPLL
port map ( PLLIN => clk0_out0,
GCLK => dclk0,
LOCKED => LOCKED,
IOCLK => SD_CLK,
SERDESSTROBE => SerDes_Strobe,
LOCK => open
);

CLK0_FB: BUFIO2FB
port map( I => SD_CLK,
O => clk0fb);
DCLK0_BUF : BUFG
port map( I => clk0_out1,
O => dclk0);

SerDes_CLK<=SD_CLK;
clk0_out<=clk0;
dclk0_out<=dclk0;
end Behavioral;

Прием данных с АЦП
CODE
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 09:15:39 01/13/2015
-- Design Name:
-- Module Name: Tochnost_FPGA_ADC_BUF - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity ADC_BUFFER is
Port (
Divclk : in STD_LOGIC;
SerDes_Strobe : in STD_LOGIC;
SerDes_CLK : in STD_LOGIC;
ADC1_D_P : in STD_LOGIC_VECTOR (11 downto 0);
ADC1_D_N : in STD_LOGIC_VECTOR (11 downto 0);
ADC1_OR_P : in STD_LOGIC;
ADC1_OR_N : in STD_LOGIC;
ADC1_DCO_P : in STD_LOGIC;
ADC1_DCO_N : in STD_LOGIC;
ADC2_D_P : in STD_LOGIC_VECTOR (11 downto 0);
ADC2_D_N : in STD_LOGIC_VECTOR (11 downto 0);
ADC2_OR_P : in STD_LOGIC;
ADC2_OR_N : in STD_LOGIC;
ADC2_DCO_P : in STD_LOGIC;
ADC2_DCO_N : in STD_LOGIC;
ADC1_DATA : out STD_LOGIC_VECTOR (47 downto 0);
ADC2_DATA : out STD_LOGIC_VECTOR (47 downto 0));
end ADC_BUFFER;

architecture Behavioral of ADC_BUFFER is

attribute IOSTANDARD : string;
attribute DIFF_TERM : string;
attribute IBUF_DELAY_VALUE : string;
attribute IFD_DELAY_VALUE : string;
attribute DATA_RATE : string;
attribute DATA_WIDTH : string;
attribute BITSLIP_ENABLE : string;
attribute SERDES_MODE : string;
attribute INTERFACE_TYPE : string;
attribute IDELAY_VALUE : string;
attribute IDELAY2_VALUE : string;
attribute IDELAY_MODE : string;
attribute ODELAY_VALUE : string;
attribute IDELAY_TYPE : string;
attribute COUNTER_WRAPAROUND : string;
attribute DELAY_SRC : string;
-- attribute SERDES_MODE : string;
attribute SIM_TAP_DELAY : string;
-- attribute DATA_RATE : string;
attribute BOX_TYPE : string;

component IBUFDS
-- synopsys translate_off
generic( DIFF_TERM : boolean := FALSE);
-- synopsys translate_on
port ( I : in std_logic;
IB : in std_logic;
O : out std_logic);
end component;
attribute IOSTANDARD of IBUFDS : component is "DEFAULT";
-- attribute IOSTANDARD of IBUFGDS : component is "LVPECL_33";
attribute DIFF_TERM of IBUFDS : component is "FALSE";
attribute IBUF_DELAY_VALUE of IBUFDS : component is "0";
attribute BOX_TYPE of IBUFDS : component is "BLACK_BOX";

component IODELAY2
port (
IDATAIN : in std_logic;
T : in std_logic;
ODATAIN : in std_logic;
CAL : in std_logic;
IOCLK0 : in std_logic;
IOCLK1 : in std_logic;
CLK : in std_logic;
INC : in std_logic;
CE : in std_logic;
RST : in std_logic;
BUSY : out std_logic;
DATAOUT : out std_logic;
DATAOUT2 : out std_logic;
TOUT : out std_logic;
DOUT : out std_logic
);
end component;

attribute IDELAY_VALUE of IODELAY2 : component is "0";
attribute IDELAY2_VALUE of IODELAY2 : component is "0";
attribute IDELAY_MODE of IODELAY2 : component is "NORMAL";
attribute ODELAY_VALUE of IODELAY2 : component is "0";
attribute IDELAY_TYPE of IODELAY2 : component is "DEFAULT";
attribute COUNTER_WRAPAROUND of IODELAY2 : component is "STAY_AT_LIMIT";
attribute DELAY_SRC of IODELAY2 : component is "IDATAIN";
attribute SERDES_MODE of IODELAY2 : component is "NONE";
attribute SIM_TAP_DELAY of IODELAY2 : component is "50";
attribute DATA_RATE of IODELAY2 : component is "SDR";
attribute BOX_TYPE of IODELAY2 : component is "BLACK_BOX";

component ISERDES2
port ( CLK0 : in std_logic;
CLK1 : in std_logic;
CLKDIV : in std_logic;
CE0 : in std_logic;
BITSLIP : in std_logic;
D : in std_logic;
RST : in std_logic;
IOCE : in std_logic;
SHIFTIN : in std_logic;
CFB0 : out std_logic;
CFB1 : out std_logic;
DFB : out std_logic;
SHIFTOUT : out std_logic;
FABRICOUT : out std_logic;
Q4 : out std_logic;
Q3 : out std_logic;
Q2 : out std_logic;
Q1 : out std_logic;
VALID : out std_logic;
INCDEC : out std_logic
);
end component;

attribute DATA_RATE of ISERDES2 : component is "SDR";
attribute DATA_WIDTH of ISERDES2 : component is "4";
attribute BITSLIP_ENABLE of ISERDES2 : component is "FALSE";
attribute SERDES_MODE of ISERDES2 : component is "NONE";
attribute INTERFACE_TYPE of ISERDES2 : component is "NETWORKING";
attribute BOX_TYPE of ISERDES2 : component is "BLACK_BOX";

signal ADC1_D:std_logic_vector(11 downto 0):=(others=>'0');
signal ADC1_D1:std_logic_vector(11 downto 0):=(others=>'0');
signal ADC1_D2:std_logic_vector(11 downto 0):=(others=>'0');
signal ADC1_D3:std_logic_vector(11 downto 0):=(others=>'0');
signal ADC1_D4:std_logic_vector(11 downto 0):=(others=>'0');
signal ADC1_D_Delayed:std_logic_vector(11 downto 0):=(others=>'0');
signal ADC2_D:std_logic_vector(11 downto 0):=(others=>'0');
signal ADC2_D1:std_logic_vector(11 downto 0):=(others=>'0');
signal ADC2_D2:std_logic_vector(11 downto 0):=(others=>'0');
signal ADC2_D3:std_logic_vector(11 downto 0):=(others=>'0');
signal ADC2_D4:std_logic_vector(11 downto 0):=(others=>'0');
signal ADC2_D_Delayed:std_logic_vector(11 downto 0):=(others=>'0');
begin

ADC1_DATA_BUFFERS:
for i in 0 to 11 generate
ADC1_D_BUF : IBUFDS
port map( I => ADC1_D_p(i),
IB => ADC1_D_n(i),
O => ADC1_D(i));
ADC1_D_IODELAY : IODELAY2
port map(
IDATAIN => ADC1_D(i),
T => '1',
ODATAIN => '0',
CAL => '0',
IOCLK0 => SerDes_CLK,
IOCLK1 => '0',
CLK => Divclk,
INC => '1',
CE => '1',
RST => '0',
BUSY => open,
DATAOUT => ADC1_D_Delayed(i),-- to SERDES
DATAOUT2 => open, -- to FPGA Logic
TOUT => open,
DOUT => open
);
ADC1_D_SERDER : ISERDES2
port map(
CLK0 => SerDes_CLK,
CLK1 => '0',
CLKDIV => Divclk,
CE0 => '1',
BITSLIP => '0',
D => ADC1_D_Delayed(i),
RST => '0',
IOCE => SerDes_Strobe,
SHIFTIN => '0',
CFB0 => open,
CFB1 => open,
DFB => open,
SHIFTOUT => open,
FABRICOUT => open, -- to FPGA Logic
Q4 => ADC1_D4(i),
Q3 => ADC1_D3(i),
Q2 => ADC1_D2(i),
Q1 => ADC1_D1(i),
VALID => open,
INCDEC => open
);

ADC1_DATA(i)<=ADC1_D1(i);
ADC1_DATA(i+12)<=ADC1_D2(i);
ADC1_DATA(i+24)<=ADC1_D3(i);
ADC1_DATA(i+36)<=ADC1_D4(i);
end generate ADC1_DATA_BUFFERS;

ADC2_DATA_BUFFERS:
for i in 0 to 11 generate
ADC2_D_BUF : IBUFDS
port map( I => ADC2_D_p(i),
IB => ADC2_D_n(i),
O => ADC2_D(i));
ADC2_D_IODELAY : IODELAY2
port map(
IDATAIN => ADC2_D(i),
T => '1',
ODATAIN => '0',
CAL => '0',
IOCLK0 => SerDes_CLK,
IOCLK1 => '0',
CLK => Divclk,
INC => '1',
CE => '1',
RST => '0',
BUSY => open,
DATAOUT => ADC2_D_Delayed(i),-- to SERDES
DATAOUT2 => open, -- to FPGA Logic
TOUT => open,
DOUT => open
);
ADC2_D_SERDER : ISERDES2
port map(
CLK0 => SerDes_CLK,
CLK1 => '0',
CLKDIV => Divclk,
CE0 => '1',
BITSLIP => '0',
D => ADC2_D_Delayed(i),
RST => '0',
IOCE => SerDes_Strobe,
SHIFTIN => '0',
CFB0 => open,
CFB1 => open,
DFB => open,
SHIFTOUT => open,
FABRICOUT => open, -- to FPGA Logic
Q4 => ADC2_D4(i),
Q3 => ADC2_D3(i),
Q2 => ADC2_D2(i),
Q1 => ADC2_D1(i),
VALID => open,
INCDEC => open
);

ADC2_DATA(i)<=ADC2_D1(i);
ADC2_DATA(i+12)<=ADC2_D2(i);
ADC2_DATA(i+24)<=ADC2_D3(i);
ADC2_DATA(i+36)<=ADC2_D4(i);
end generate ADC2_DATA_BUFFERS;
ADC1_OR_BUF : IBUFDS
port map( I => ADC1_OR_p,
IB => ADC1_OR_n,
O => open);
ADC1_DCO_BUF : IBUFDS
port map( I => ADC1_DCO_p,
IB => ADC1_DCO_n,
O => open);
ADC2_OR_BUF : IBUFDS
port map( I => ADC2_OR_p,
IB => ADC2_OR_n,
O => open);
ADC2_DCO_BUF : IBUFDS
port map( I => ADC2_DCO_p,
IB => ADC2_DCO_n,
O => open);

end Behavioral;
Причина редактирования: Используйте codebox для оформления длинных кусков кода (с) модератор

Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение


Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
serjj
сообщение Jan 13 2015, 13:19
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 527
Регистрация: 4-06-14
Из: Санкт-Петербург
Пользователь №: 81 866



У вас скорее всего BUFPLL и ножки входные в разных IO банках оказались, а компонент BUFPLL жёстко привязан к своему банку. Скидайте их констрейнами в один банк, можно через ГУИ прям, тогда должно развестись
Go to the top of the page
 
+Quote Post
ZZZRF413
сообщение Jan 14 2015, 06:33
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 26-07-09
Из: Нижний Новгород
Пользователь №: 51 578



Цитата(serjj @ Jan 13 2015, 17:19) *
У вас скорее всего BUFPLL и ножки входные в разных IO банках оказались, а компонент BUFPLL жёстко привязан к своему банку. Скидайте их констрейнами в один банк, можно через ГУИ прям, тогда должно развестись

serjj, большое спасибо! Действительно они находятся в разных банках. Прописал позицию вручную через LOC для PLLBUF и BUFIO2 и все заработало. Единственное только пришлось упростить обратную связь убрав BUFIO2FB.
Go to the top of the page
 
+Quote Post
Bad0512
сообщение Jan 14 2015, 10:42
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 802
Регистрация: 11-05-07
Из: Томск
Пользователь №: 27 650



Цитата(ZZZRF413 @ Jan 14 2015, 12:33) *
serjj, большое спасибо! Действительно они находятся в разных банках. Прописал позицию вручную через LOC для PLLBUF и BUFIO2 и все заработало. Единственное только пришлось упростить обратную связь убрав BUFIO2FB.

Можно сделать проще, без PLL. Но для этого надо завести DCO с обеих АЦПеек на соответствующий клоковый вход. И чтобы все биты данных были в соответствующем банке.
Go to the top of the page
 
+Quote Post
ZZZRF413
сообщение Jan 14 2015, 13:53
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 26-07-09
Из: Нижний Новгород
Пользователь №: 51 578



Ну вот рано я обрадовался...
Теперь тайминги никакие... Fmax 13 MHz
Цитата(Bad0512 @ Jan 14 2015, 14:42) *
Можно сделать проще, без PLL. Но для этого надо завести DCO с обеих АЦПеек на соответствующий клоковый вход. И чтобы все биты данных были в соответствующем банке.

К сожалению так сделать нельзя. Плата физически уже есть, а DCO на клоковый вход не заведен sad.gif

Я думаю тут надо попробовать 2 PLL поставить. Один в банке где, вход тактового сигнала, а другой в банке где входы данных с АЦП.
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Timmy
сообщение Jan 15 2015, 08:39
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



Цитата(ZZZRF413 @ Jan 14 2015, 16:53) *
К сожалению так сделать нельзя. Плата физически уже есть, а DCO на клоковый вход не заведен sad.gif

На 400Msps это не проблема. Можно применить тактирование на 800МГц и динамическую подстройку фазы PLL по фронтам ADC_DCO с обычных пинов. Причём для каждого АЦП свою фазу, если получится подключить к разным АЦП разные выходы PLL. Данное решение получится более точным, чем непосредственное использование ADC_DCO с клокового входа.
Go to the top of the page
 
+Quote Post
ZZZRF413
сообщение Jan 16 2015, 11:37
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 26-07-09
Из: Нижний Новгород
Пользователь №: 51 578



Цитата(Timmy @ Jan 15 2015, 12:39) *
На 400Msps это не проблема. Можно применить тактирование на 800МГц и динамическую подстройку фазы PLL по фронтам ADC_DCO с обычных пинов. Причём для каждого АЦП свою фазу, если получится подключить к разным АЦП разные выходы PLL. Данное решение получится более точным, чем непосредственное использование ADC_DCO с клокового входа.


Что-то я не совсем понял... "если получится подключить к разным АЦП разные выходы PLL" - это как? Тактовый сигнал на АЦП не идет с FPGA, его формирует отдельная микросхема на плате - AD9518. Она же формирует тактовый сигнал на ПЛИС. Или имеется ввиду схема наподобии как в приложении?
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
SM
сообщение Jan 16 2015, 12:23
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Вообще, DCO заводить на клоковый пин вредно. DCO надо рассматривать как вход данных, так как частота DCO может меняться в зависимости от настройки АЦП (его там делить можно, уменьшая частоту дискретизации). Поэтому, лучше всего, если на клоковый пин заведен входной клок АЦП, а там уже вполне себе четкие Tco(min) и Tco(max) прописаны у АЦП (в даташите на АЦП, Tpd/Tcpd), так что можно спокойно прописать констрейны на сетап и холд для FPGA по DCO и данным, там вилка получается достаточной, чтобы быть выдержанной. Ошибки по этим констрейнам можно исправлять как подстройкой фазы входного клока на PLL (фиксированное, на конкретное числовое значение), так и изменением задержки внутри I/O пада (если таковая доступна для конкретной FPGA)

Ну а DCO использовать совместно с данными - данное считается валидным только тогда, когда на DCO (с DDR-приемом) произошла смена уровня.
Go to the top of the page
 
+Quote Post
Timmy
сообщение Jan 18 2015, 15:48
Сообщение #9


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



Цитата(ZZZRF413 @ Jan 16 2015, 14:37) *
Что-то я не совсем понял... "если получится подключить к разным АЦП разные выходы PLL" - это как? Тактовый сигнал на АЦП не идет с FPGA, его формирует отдельная микросхема на плате - AD9518. Она же формирует тактовый сигнал на ПЛИС. Или имеется ввиду схема наподобии как в приложении?

Фразу надо уточнить - к входам от разных АЦП разные выходы PLL. Каждому АЦП свой PLLBUF.
Go to the top of the page
 
+Quote Post
dm.pogrebnoy
сообщение Jan 19 2015, 06:52
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 747
Регистрация: 11-04-07
Пользователь №: 26 933



Цитата(SM @ Jan 16 2015, 15:23) *
Вообще, DCO заводить на клоковый пин вредно. DCO надо рассматривать как вход данных, так как частота DCO может меняться в зависимости от настройки АЦП (его там делить можно, уменьшая частоту дискретизации). Поэтому, лучше всего, если на клоковый пин заведен входной клок АЦП, а там уже вполне себе четкие Tco(min) и Tco(max) прописаны у АЦП (в даташите на АЦП, Tpd/Tcpd), так что можно спокойно прописать констрейны на сетап и холд для FPGA по DCO и данным, там вилка получается достаточной, чтобы быть выдержанной. Ошибки по этим констрейнам можно исправлять как подстройкой фазы входного клока на PLL (фиксированное, на конкретное числовое значение), так и изменением задержки внутри I/O пада (если таковая доступна для конкретной FPGA)

Ну а DCO использовать совместно с данными - данное считается валидным только тогда, когда на DCO (с DDR-приемом) произошла смена уровня.


Интересно, для 1-3 ГГц АЦП тоже входной такт АЦП заводить на ПЛИС? По-моему лишнее это, все отлично работает с DCO, а то что он меняться может, обычно жестко завязано на режим работы преобразователя, с которым нужно заранее определиться.

По топику, я бы поставил в IOB фазовый детектор, по которому подстраивал бы фазу сигнала с DCM.


--------------------
Go to the top of the page
 
+Quote Post
SM
сообщение Jan 19 2015, 08:58
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(dm.pogrebnoy @ Jan 19 2015, 09:52) *
Интересно, для 1-3 ГГц АЦП тоже входной такт АЦП заводить на ПЛИС? По-моему лишнее это, все отлично работает с DCO, а то что он меняться может, обычно жестко завязано на режим работы преобразователя, с которым нужно заранее определиться.


Это, как сказать. У меня, к примеру, частотой DCO рулят программисты, как хотят. А система должна работать. Для 1-3 ГГц, я думаю, все будет по-другому, DCO надо будет уже заводить на DQS-входы и использовать примитивы приема сигнала и переноса ее на внутреннюю тактовую от DDR памяти. И, вообще, я не знаю таких ПЛИС, которые могут принять по LVDS 2-3 гигабита. Это уже прерогатива гигабитных трансиверов.
Go to the top of the page
 
+Quote Post
dm.pogrebnoy
сообщение Jan 19 2015, 10:40
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 747
Регистрация: 11-04-07
Пользователь №: 26 933



Цитата(SM @ Jan 19 2015, 11:58) *
Это, как сказать. У меня, к примеру, частотой DCO рулят программисты, как хотят. А система должна работать. Для 1-3 ГГц, я думаю, все будет по-другому, DCO надо будет уже заводить на DQS-входы и использовать примитивы приема сигнала и переноса ее на внутреннюю тактовую от DDR памяти. И, вообще, я не знаю таких ПЛИС, которые могут принять по LVDS 2-3 гигабита. Это уже прерогатива гигабитных трансиверов.


Во всех устройствах, по моему опыту, DCO достаточно жестко задается конфигурацией аппаратной части, и просто так поменять не получится (не заработает). Хотя не исключаю возможности других вариантов использования DCO, надо смотреть конкретную м/сх.
И обычно получается не 2-3 гигабита, а меньше.
ADS5400 1 ГГц тактовая, 500 МБит LVDS, 250 МГц в DDR. Принимает Spartan-6.
ADC08300 3 ГГц таковая, 700 Мбит LVDS, 350 МГц в DDR. Принимал когда-то даже Virtex-4, cейчас Virtex-6.

Для более скоростных преобразователей JESD204 входит в моду. Там да, гигабитные приемо-передатчики.


--------------------
Go to the top of the page
 
+Quote Post
SM
сообщение Jan 19 2015, 10:52
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(dm.pogrebnoy @ Jan 19 2015, 13:40) *
и просто так поменять не получится (не заработает).

Вот именно поэтому, я и описал, как сделать так, чтобы заработало. И заодно убить второго зайца, о котором тема.
Сколько я видел АЦП от AD - там у всех (виденных) имеется регистр 0x0B - Clock divide (global) - которым можно менять частоту преобразования, и, соотв., DCO. Но, при этом, тайминги CLK->[DCO, DATA] не меняются. Только фронты на них реже становятся.

Цитата(dm.pogrebnoy @ Jan 19 2015, 13:40) *
250 МГц в DDR.

Не думаю, что при 250 МГц будут проблемы с приемом DCO как DDR-бита данных. У меня DCO может быть от 125/16 (чуть больше 7) до 125 МГц, но запас в обе стороны по отчету STA - по холду 1.6 нс, по сетапу 0.866 нс, это значит, что Fmax в этом месте 325 МГц (с учетом, что это DDR, то есть, за период берется пол-периода). Хотя, тут еще надо учитывать, какая вилка у min <= Tpd <= max у конкретного АЦП
Go to the top of the page
 
+Quote Post
Bad0512
сообщение Jan 20 2015, 03:29
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 802
Регистрация: 11-05-07
Из: Томск
Пользователь №: 27 650



Клок с АЦП заводить на ПЛИС напрямую не рекомендуется по следующим причинам :
В случае Схемы типа источник клока -> clock distributor с двумя выходами -> с его выходов один клок идёт на ПЛИС, а другой на АЦП.
Здесь появляется в цепи клока клок дистрибьютор - это дополнительный источник джиттера, что ухудшает характеристики АЦП. Кроме этого ещё и дополнительное
потребление плюс стоимость самого компонента.
Кроме того в этом варианте разница в путях распространения distributor->ADC и distributor->FPGA неконтролируема и нигде не учитывается, на высоких частотах может быть критично.
Как правило времянки выходных данных АЦП нормируются именно по отношению к DCO, а не к сэмплирующему клоку. И это неслучайно. Кроме того в продвинутых моделях АЦП-ЦАП есть механизм
плавной подстройки DCO относительно данных, что практически исключает необходимость геморроя с IDELAY2 внутри ПЛИС - зачем плодить механизмы подстройки фазы если они уже есть?
В общем, DCO как раз для этой цели и придуман чтобы сопровождать данные, и да, его частота в общем случае может и не совпадать с сэмплирующей (например если выход полифазный).
Это не баг, это фича. Делается для большего удобства дизайна интерфейсов к ПЛИС.
З Ы Для шустрых АЦП JESD204 - не единственный вариант, хотя и очень распространённый. Некоторые разбивают выход на несколько фаз, плюс фазы работают в DDR режиме.
Для исключения зависящих от цифровых данных спурсов применяют скремблирование.
Go to the top of the page
 
+Quote Post
SM
сообщение Jan 20 2015, 09:02
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(Bad0512 @ Jan 20 2015, 06:29) *
Кроме того в этом варианте разница в путях распространения distributor->ADC и distributor->FPGA неконтролируема и нигде не учитывается,

Ну это в корне неверно, она учитывается добавлением соответствующего пессимизма к setup и hold констрейнам (set_input_delay), равного джиттер + разница в путях. И отлично контролируема, так как все это хорощо документировано (для дистрибьютеров), или рассчитывается (для длин дорожек и емкостей нагрузок) - Смотрим отчет STA, и видим все как на ладони, сколько запаса по чему.

Цитата(Bad0512 @ Jan 20 2015, 06:29) *
Как правило времянки выходных данных АЦП нормируются именно по отношению к DCO, а не к сэмплирующему клоку.

Как правило, они нормируются и к тому, и к другому. Для DCO определяют расхождение +- от данных, а для входного клока - время распространения от входного клока до DCO и до данных.

PS.
Офигенное удобство - делать переход с клока DCO на основной клок ПЛИС для каждого подключенного АЦП, когда еще и заранее неизвестно, какая частота на DCO придет, как ее вздумается пользователю поделить внутри АЦП, докучи, по-разному для нескольких АЦП... И еще. Пока не настроен АЦП, клок с DCO идет, как правило не в том виде - например, CMOS, вместо LVDS, который нужен ПЛИСе. Это еще одна причина не использовать его как основной клок ПЛИС, а брать с дистрибьютера отдельный. Нормальный дистрибьютер джиттера привносит так мало, что им пренебречь можно.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 00:22
Рейтинг@Mail.ru


Страница сгенерированна за 0.01549 секунд с 7
ELECTRONIX ©2004-2016