Art55555 0 August 6, 2020 Posted August 6, 2020 · Report post Система LTC2195 и Артикс. Раньше работало всё на IDDR-ах и смещённой фазе PLL. Время от времени возникали проблемы с задержкой, подбиралось руками и всё работало дальше. Назрел момент автоматической настройки всех задержек для нормальной работы системы. Идём по классической схеме - Перевод в необходимый режим выдачи данных. АЦП в режим Test Pattern, подстройка бит, проверка стабильности выдаваемых значений. Редактирование форматов и т.д. Переход в обычный режим. В результате сигнал "плохой", выбросы, явное несоответствие ожиданиям. Решил проверить связку IDELAYЕ2-ISERDES по линии DCO. На выходе вижу постоянную картину - А(1010). Подача каманды на IDELAYЕ2 даёт результат на 1 такт(( потом возвращает значение А (это после десереализации). Понимаю, что сдвиг IDELAYЕ2 должен работать по схеме A-шум-5-шум-А... Этого не происходит. Кто имел подобный опыт? ---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 11:13:56 07/15/2020 -- Design Name: -- Module Name: ltc_2195_v2 - 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; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Library UNISIM; use UNISIM.vcomponents.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 ltc_2195_v2 is port ( out1a_p : in std_logic; -- такт с АЦП1 + out1a_n : in std_logic; -- такт с АЦП1 - out1b_p : in std_logic; -- такт с АЦП2 + out1b_n : in std_logic; -- такт с АЦП2 - out1c_p : in std_logic; -- такт с АЦП1 + out1c_n : in std_logic; -- такт с АЦП1 - out1d_p : in std_logic; -- такт с АЦП2 + out1d_n : in std_logic; -- такт с АЦП2 - out2a_p : in std_logic; -- такт с АЦП1 + out2a_n : in std_logic; -- такт с АЦП1 - out2b_p : in std_logic; -- такт с АЦП2 + out2b_n : in std_logic; -- такт с АЦП2 - out2c_p : in std_logic; -- такт с АЦП1 + out2c_n : in std_logic; -- такт с АЦП1 - out2d_p : in std_logic; -- такт с АЦП2 + out2d_n : in std_logic; -- такт с АЦП2 - FR_p : in std_logic; -- такт с АЦП2 + FR_n : in std_logic; -- такт с АЦП2 - DCO_p : in std_logic; -- такт с АЦП2 + DCO_n : in std_logic; -- такт с АЦП2 - reset: in std_logic; clk: in std_logic; clk_in_2x: in std_logic; clk125: out std_logic; data_all_obr1 : out std_logic_vector(15 downto 0); data_all_obr2 : out std_logic_vector(15 downto 0); aclk_div_out : out std_logic; aclk_div2_out : out std_logic; calib_in_dco: in std_logic; calib_in_data: in std_logic; dco_pattern_reverse : in std_logic; calibration_detection: out std_logic; calib_data_done : out std_logic; calib_dco_done : out std_logic; test_in : in std_logic_vector(15 downto 0); test0 : out std_logic_vector(15 downto 0); test1 : out std_logic_vector(15 downto 0); test2 : out std_logic_vector(15 downto 0); test3 : out std_logic_vector(15 downto 0); test4 : out std_logic_vector(15 downto 0); test5 : out std_logic_vector(15 downto 0) ); end ltc_2195_v2; architecture Behavioral of ltc_2195_v2 is component icon_ddr PORT ( CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); CONTROL1 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); end component; component vio_ddr2 PORT ( CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); -- CLK : IN STD_LOGIC; ASYNC_OUT : OUT STD_LOGIC_VECTOR(24 DOWNTO 0)); -- SYNC_OUT: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); end component; component ila_ddr PORT ( CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); CLK : IN STD_LOGIC; TRIG0 : IN STD_LOGIC_VECTOR(31 DOWNTO 0); TRIG1 : IN STD_LOGIC_VECTOR(31 DOWNTO 0); TRIG2 : IN STD_LOGIC_VECTOR(31 DOWNTO 0); TRIG3 : IN STD_LOGIC_VECTOR(7 DOWNTO 0); TRIG4 : IN STD_LOGIC_VECTOR(7 DOWNTO 0) ); end component; type bit1 is array (0 to 7) of std_logic; type bit8 is array (0 to 7) of std_logic_vector(7 downto 0); type bit16 is array (0 to 7) of std_logic_vector(15 downto 0); type bit18 is array (0 to 7) of std_logic_vector(17 downto 0); signal TRIG0 : STD_LOGIC_VECTOR(31 DOWNTO 0); signal TRIG1 : STD_LOGIC_VECTOR(31 DOWNTO 0); signal TRIG2 : STD_LOGIC_VECTOR(31 DOWNTO 0); signal TRIG3 : STD_LOGIC_VECTOR(7 DOWNTO 0); signal TRIG4 : STD_LOGIC_VECTOR(7 DOWNTO 0); signal control0,control1 : STD_LOGIC_VECTOR(35 DOWNTO 0); signal contro20,contro21 : STD_LOGIC_VECTOR(35 DOWNTO 0); signal ASYNC_OUT : STD_LOGIC_VECTOR(24 DOWNTO 0); signal start_vio : std_logic:='0'; --signal vio: std_logic_vector(7 downto 0):=x"00"; signal indicator: std_logic_vector(7 downto 0):=x"00"; signal aclk,d_aclk: std_logic; signal adcidlyctrlrdy: std_logic; signal intclkctrldlyrst : std_logic:='0'; signal aclk_main : std_logic:='0'; signal set_idelay_dco1 : std_logic:='0'; signal IntBitClkRst : std_logic:='0'; ------------- signal bitslip_data,bitslip_data2 : bit1; signal set_idelay_data : bit1; constant Low : std_logic := '0'; signal LowNibble : std_logic_vector(4 downto 0) := "00000"; constant High : std_logic := '1'; signal aclk_div :std_logic:='0'; signal aclk_div2 :std_logic:='0'; signal dco_calib_out,dco_calib_out_t : std_logic_vector(7 downto 0) := (others => '0'); signal dco_calib_out2,dco_calib_out_t2 : std_logic_vector(7 downto 0) := (others => '0'); signal bitslip_dco1 :std_logic:='0'; signal d_adc,d_adc2 : bit1; signal d_adc_d,d_adc_d2 : bit1; signal dat_x,dat_x2,fco_x : bit8; signal dat_x_finish,dat_x_finish2 : bit8; signal pattern,pattern2 : bit8; signal bitslip_data_all : std_logic:='0'; type state_type5 is (S0,S1,S2,S3,S4); signal STATE: state_type5; signal DCO :std_logic:='0'; signal DCO_fb :std_logic:='0'; signal clk2x :std_logic:='0'; signal cnt : std_logic_vector(7 downto 0) := (others => '0'); signal cnt_16 : std_logic_vector(17 downto 0) := (others => '0'); begin aclk_div_out<=aclk_div; IBUFGDS_inst2 : IBUFDS generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => FALSE)--, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards -- IOSTANDARD => "SSTL18_II") port map ( O => aclk, -- Clock buffer output I => DCO_p, -- Diff_p clock buffer input (connect directly to top-level port) IB => DCO_N -- Diff_n clock buffer input (connect directly to top-level port) ); xIDELAY: IDELAYE2 generic map ( SIGNAL_PATTERN => "CLOCK", REFCLK_FREQUENCY => 200.0, HIGH_PERFORMANCE_MODE => "TRUE", --FINEDELAY => "BYPASS", DELAY_SRC => "IDATAIN", -- DELAY_SRC => "both", CINVCTRL_SEL => "FALSE", IDELAY_TYPE => "VARIABLE",--"VAR_LOAD_PIPE",--"VARIABLE", IDELAY_VALUE => 16, PIPE_SEL => "FALSE" ) port map ( DATAIN => '0',--, IDATAIN => aclk, DATAOUT => d_aclk, C => aclk_div, --clk,--aclk_div, --200 MHz CE => set_idelay_dco1, --'1',-- INC => '1', LD => IntClkCtrlDlyRst, -- '0',--IntClkCtrlDlyRst, --идет с VIO CNTVALUEIN => LowNibble, --идет с VIO CNTVALUEOUT => open, REGRST => IntClkCtrlDlyRst,--'0',--'0',-- CINVCTRL => '0', LDPIPEEN => '0' ); bufio_adc: BUFIO port map ( i => d_aclk, o => aclk_main ); --FB BUFR_ins1 : BUFR generic map ( BUFR_DIVIDE => "2", -- Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8" SIM_DEVICE => "7SERIES" -- Must be set to "7SERIES" ) port map ( O => aclk_div, -- 1-bit output: Clock output port CE => '1', -- 1-bit input: Active high, clock enable (Divided modes only) CLR => reset, -- 1-bit input: Active high, asynchronous clear (Divided modes only) I => d_aclk -- 1-bit input: Clock buffer input driven by an IBUFG, MMCM or local interconnect ); x_IDELAYCTRL : IDELAYCTRL port map (REFCLK => clk_in_2x, RST => reset, RDY => AdcIdlyCtrlRdy); xISERDES1113: ISERDESE2 generic map ( SERDES_MODE => "MASTER", INTERFACE_TYPE => "NETWORKING", IOBDELAY => "Both",--"IBUF",-- DATA_RATE => "DDR", DATA_WIDTH => 4, DYN_CLKDIV_INV_EN => "FALSE", DYN_CLK_INV_EN => "FALSE", NUM_CE => 1, OFB_USED => "FALSE", INIT_Q1 => '0', INIT_Q2 => '0', INIT_Q3 => '0', INIT_Q4 => '0', SRVAL_Q1 => '0', SRVAL_Q2 => '0', SRVAL_Q3 => '0', SRVAL_Q4 => '0' ) port map ( -- Registered outputs Q1 => dco_calib_out(0), Q2 => dco_calib_out(1), Q3 => dco_calib_out(2), Q4 => dco_calib_out(3), Q5 => open,--dco_calib_out(4), Q6 => open,--dco_calib_out(5), Q7 => open,--dco_calib_out(6), Q8 => open,--dco_calib_out(7), -- Unregistered output O => open,--IntBitClk, --ser_dat(ii), -- Carry out for bit expansion SHIFTOUT1 => open, SHIFTOUT2 => open, -- Serial data in from PAD or IODELAY D => aclk, -- '0',-- aclk,-- DDLY =>'0', --d_aclk, -- Carry in for bit expansion SHIFTIN1 => '0', SHIFTIN2 => '0', -- Clock signals CLK => aclk_main,-- high-speed clock CLKB => not aclk_main, -- inverted clock CLKDIV => aclk_div,-- divided clock -- Clock enable CE1 => '1', CE2 => '0', -- Reset RST => IntBitClkRst, --rst(i), Reset,-- --- NOT USED BITSLIP => bitslip_dco1,--'1', --'0', -- bitslip operation------------------- OCLK => '0', -- high-speed clock OCLKB => '0', -- inverted clock DYNCLKSEL => '0', DYNCLKDIVSEL => '0', CLKDIVP => '0', OFB => '0' -- feedback path ); process (aclk_div) begin if(aclk_div'event and aclk_div='1')then dco_calib_out_t <= dco_calib_out; trig0(7 downto 0)<= dat_x_finish(0); trig1(7 downto 0)<= dat_x_finish(1); trig2(7 downto 0)<= dat_x_finish(2); trig3(7 downto 0)<= dat_x_finish(3); -- trig4(7 downto 0)<= dat_x_finish(0);--dat_x_finish(4); trig4( 0)<= set_idelay_dco1; end if; end process; process (aclk_div) begin if (rising_edge(aclk_div)) then cnt_16<=cnt_16+1; case (STATE) is when S0 => if dco_calib_out_t=x"0A" then STATE<=S1;set_idelay_dco1<='1'; cnt_16<= (others => '0'); end if;--cnt<=cnt+1; when S1 => -- STATE<=S2; set_idelay_dco1<='0'; when S2 => if cnt_16(17)='1' then STATE<=S3; end if;-- when S3 => if dco_calib_out_t=x"05" then STATE<=S4; else STATE<=S0; end if; when S4 => when others =>null; end case; end if; end process; -- trig0(7 downto 0)<=dco_calib_out_t; process (aclk_div) begin if(aclk_div'event and aclk_div='1')then -- test0 <= dat_x_finish(0)(3 downto 0)&dat_x_finish(1)(3 downto 0)&dat_x_finish(2)(3 downto 0)&dat_x_finish(3)(3 downto 0); -- test1 (3 downto 0)<= dat_x_finish(4)(3 downto 0); -- test2 (3 downto 0)<= dco_calib_out(3 downto 0); -- test3 (3 downto 0)<= ; -- test4 (3 downto 0)<= test0(7 downto 0)<= dat_x_finish(0); test1(7 downto 0)<= dat_x_finish(1); test2(7 downto 0)<= dat_x_finish(2); -- test3(7 downto 0)<= dat_x_finish(3);--dat_x_finish(3); test3( 0)<= set_idelay_dco1;--dat_x_finish(3); -- test4(7 downto 0)<= dat_x_finish(4);--dat_x_finish(3); test4(7 downto 0)<= dco_calib_out_t;--dat_x_finish(4); -- test4(7 downto 0)<= cnt; end if; end process; -------------------------------------------------------- ibuf_2a: ibufds generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => TRUE -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards ) port map (i => out2a_p, iB => out2a_n, o => d_adc(0)); ibuf_2b: ibufds generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => TRUE -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards ) port map (i => out2b_p, iB => out2b_n, o => d_adc(1)); ibuf_2c: ibufds generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => TRUE -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards ) port map (i => out2c_p, iB => out2c_n, o => d_adc(2)); ibuf_2d: ibufds generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => TRUE -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards ) port map (i => out2d_p, iB => out2d_n, o => d_adc(3)); ibuf_FR: ibufds generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => TRUE -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards ) port map (i => FR_p, iB => FR_n, o => d_adc(4)); gADC_IN2113: for i in 0 to 4 generate -- xIDELAY: IDELAYE2 -- generic map ( -- SIGNAL_PATTERN => "DATA", -- REFCLK_FREQUENCY => 200.0, -- HIGH_PERFORMANCE_MODE => "TRUE", -- --FINEDELAY => "BYPASS", -- DELAY_SRC => "IDATAIN", -- CINVCTRL_SEL => "FALSE", -- IDELAY_TYPE => "VARIABLE",--"VAR_LOAD_PIPE",--"VARIABLE", -- IDELAY_VALUE => 16, -- PIPE_SEL => "FALSE" -- ) -- port map ( -- DATAIN => '0',--, -- IDATAIN => d_adc(i), -- DATAOUT => d_adc_d(i), -- C => clk,--aclk_div, --200 MHz -- CE => set_idelay_data(i), -- INC => '1', -- LD => '1',--LD, --идет с VIO -- CNTVALUEIN => "00011",--LowNibble, --идет с VIO -- CNTVALUEOUT => open, -- REGRST => IntClkCtrlDlyRst,--'0',--'0',-- -- CINVCTRL => '0', -- LDPIPEEN => '0' -- ); xISERDES1112: ISERDESE2 generic map ( SERDES_MODE => "MASTER", INTERFACE_TYPE => "NETWORKING", IOBDELAY => "IBUF", ---"NONE", --"IBUF", "Both",--"IFD", DATA_RATE => "DDR", DATA_WIDTH => 4, DYN_CLKDIV_INV_EN => "FALSE", DYN_CLK_INV_EN => "FALSE", NUM_CE => 1, OFB_USED => "FALSE", INIT_Q1 => '0', INIT_Q2 => '0', INIT_Q3 => '0', INIT_Q4 => '0', SRVAL_Q1 => '0', SRVAL_Q2 => '0', SRVAL_Q3 => '0', SRVAL_Q4 => '0' ) port map ( -- Registered outputs Q1 => dat_x(i)(0), Q2 => dat_x(i)(1), Q3 => dat_x(i)(2), Q4 => dat_x(i)(3), Q5 => open,--dat_x(i)(4), Q6 => open,--dat_x(i)(5), Q7 => open,--dat_x(i)(6), Q8 => open,--dat_x(i)(7), -- Unregistered output O => open, --ser_dat(ii), -- Carry out for bit expansion SHIFTOUT1 => open, SHIFTOUT2 => open, -- Serial data in from PAD or IODELAY D => '0',--d_adc_d(i),--'0', DDLY => d_adc(i),-- '0',-- d_adc_d(i),--'0',--d_adc_d(i), -- Carry in for bit expansion SHIFTIN1 => '0', SHIFTIN2 => '0', -- Clock signals CLK => aclk_main,-- high-speed clock CLKB => not aclk_main, -- inverted clock CLKDIV => aclk_div,-- divided clock -- Clock enable CE1 => '1', CE2 => '1', -- Reset RST => Reset,--IntBitClkRst, --rst(i), --- NOT USED BITSLIP => bitslip_data(i),--bitslip_data_all,--'0', -- OCLK => '0', -- high-speed clock OCLKB => '0', -- inverted clock DYNCLKSEL => '0', DYNCLKDIVSEL => '0', CLKDIVP => '0', OFB => '0' -- feedback path ); process( aclk_div ) begin if(aclk_div'event and aclk_div='1') then dat_x_finish(i)<=dat_x(i)(7 downto 0); end if; end process; end generate; process( clk_in_2x ) begin if(clk_in_2x'event and clk_in_2x='1') then cnt<=cnt+1; end if; end process; -- set_idelay_dco1<=test_in(0); bitslip_data(0) <=test_in(1 ); bitslip_data(1) <=test_in(2 ); bitslip_data(2) <=test_in(3 ); bitslip_data(3) <=test_in(4 ); -- set_idelay_data(0) <=test_in(2 ); -- set_idelay_data(1) <=test_in(4 ); -- set_idelay_data(2) <=test_in(6 ); -- set_idelay_data(3) <=test_in(8 ); -- bitslip_data(4) <=test_in(9 ); -- set_idelay_data(4) <=test_in(10); end Behavioral; Quote Share this post Link to post Share on other sites More sharing options...
des00 14 August 7, 2020 Posted August 7, 2020 · Report post поставьте в режим VAR_LOAD и проверьте поведение, чтобы гарантировать однозначность установленной задержки. Quote Share this post Link to post Share on other sites More sharing options...
Art55555 0 August 7, 2020 Posted August 7, 2020 · Report post Да, сделал так. Данные реагируют, гуляют, как на тестовой паттерне, так и на реальном сигнале. А вот DCO стоит намерво(( "А" и всё. Quote Share this post Link to post Share on other sites More sharing options...
des00 14 August 10, 2020 Posted August 10, 2020 · Report post On 8/7/2020 at 8:37 PM, Art55555 said: Да, сделал так. Данные реагируют, гуляют, как на тестовой паттерне, так и на реальном сигнале. А вот DCO стоит намерво(( "А" и всё. оке, значит в управлении нет косяка, что записали то и читается, никто задержку не меняет. Тогда какая у вас частота DCO и частота калибровки задержки? Не работал с этим АЦП, не знаю что там на DCO) на 200МГц, 1 шаг задержки у вас 78пс, всего шагов 31, т.е. вы можете задержать на половину периода частоты 200МГц. Quote Share this post Link to post Share on other sites More sharing options...
Крюк 0 September 21, 2020 Posted September 21, 2020 · Report post Предстоит сопряжение 4-канального высокоскоростного АЦП AD9253( две линии данных на канал АЦП, 80MHz частота выборки, 640 MHz частота передаче по одной из линий) с Zynk Ultrascale+. Пока только начинаю разбираться. По материалам не пойму как в проектах используется сигнал кадровой синхронизации, идущий с АЦП? Просто в Test Pattern синхронизируемся по информации, и потом работаем в основном режиме без использования сигнала кадровой синхронизации? Зачем тогда с АЦП выдается сигнал FCO? Затем, требуется ли динамическое выравнивание фазы в основном режиме? Quote Share this post Link to post Share on other sites More sharing options...
doom13 0 September 21, 2020 Posted September 21, 2020 · Report post Для Zynq UltraScale+ смотрите в сторону High Speed SelectIO. Quote Share this post Link to post Share on other sites More sharing options...
Art55555 0 September 24, 2020 Posted September 24, 2020 · Report post Проблему победить удалось. Всем спасибо за советы. К сожалению, ни один "ударный" совет не помог решить проблему, но в комплексе, да. В итоге было произведено огромное количество опытов, перепробованы разные режимы, скорости. Самое грустное в этой истории - что test pattetn выдаётся всегда, без сбоев при различных значениях задержки (только bitslip-ы нужно правильно подавать). Но после того, как мы на выходе видим стабильный тестовый сигнал, при переключении на "боевой" режим, всё равно были видны искажения по некоторым битам.(( Отвечая пользователю aem скажу, что в ряде ацп вообще не использую фрейм, а просто даю тестовый сигнал, который однозначно позволяет идентифицировать старший бит. Например, последовательность 11001001 - а далее кувыркаемся, изменяем задержки и битслипим. Что касается данного проекта, то да, я менял вручную величину задержки. Искал, когда совсем всё нестабильно, находил момент, когда было стабильно, двигался дальше, и далее момент, когда опять нестабильно. Искал "середину", "глазок" между этих двух значений и ставил посредине. Ещё раз, спасибо за помощь. Quote Share this post Link to post Share on other sites More sharing options...
Крюк 0 September 25, 2020 Posted September 25, 2020 · Report post 20 hours ago, Art55555 said: Отвечая пользователю aem скажу, что в ряде ацп вообще не использую фрейм, а просто даю тестовый сигнал, который однозначно позволяет идентифицировать старший бит. Например, последовательность 11001001 - а далее кувыркаемся, изменяем задержки и битслипим. Что касается данного проекта, то да, я менял вручную величину задержки. Искал, когда совсем всё нестабильно, находил момент, когда было стабильно, двигался дальше, и далее момент, когда опять нестабильно. Искал "середину", "глазок" между этих двух значений и ставил посредине. Задержка с линии данных данных, или фронт битовой частоты двигали? И автоматическую настройку всех задержек не делали? Только ручную на этапе отладки для каждого канала АЦП? Quote Share this post Link to post Share on other sites More sharing options...