|
|
  |
Прием данных с АЦП AD9681 |
|
|
|
Oct 18 2017, 12:13
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 7-10-10
Пользователь №: 59 981

|
Цитата(Алга @ Oct 10 2017, 09:43)  У меня за основу принят xapp585. В системе 4 отдельных корпуса АЦП другого типа. Все работает. Начинал с харр524, Казалось будет проще. Но в итоге отказался и перешел на xapp585.
Не заметил один из вопросов. Как определяются границы бита? Принимаются данные через сердес и запоминаются Далее меняется задержка. Но при очередной следующей задержке, если сменимись данные (код данных), то это означает что попали на фронт смены бита. Так определяются границы задержек стабильного приема данных и вычисляется середина этого участка, которая и окончательно устанавливается. Все это описано в xapp'ах и даже лучше. Отправил Вам в личку сообщение. Посмотрите, плз. Спасибо!
|
|
|
|
|
Oct 18 2017, 12:18
|
Частый гость
 
Группа: Участник
Сообщений: 135
Регистрация: 19-10-13
Пользователь №: 78 795

|
Цитата(Flip-fl0p @ Oct 9 2017, 23:04)  А можно про этот процесс чуть подробнее ? Допустим есть некий АЦП который управляется по SPI. Мы либо запускаем АЦП в "нормальном" режиме - когда он гонит данные. Либо запускаем АПЦ в режиме калибровки - когда он гонит тестовую последовательность. Читал доки от xilinx но так и не понял как определяются границы бита, чтобы выставить клок в центр данных. Пропускаем данные через блоки IDELAYE2, перебираем все возможные задержки. Засекаем две задержки - минимальную и максимальную, при которых тестовая последовательность или счетчик проходят тест. Берем ту, что по середине - попадаем на центр окна.
|
|
|
|
|
Oct 18 2017, 12:35
|

В поисках себя...
   
Группа: Свой
Сообщений: 729
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140

|
Цитата(Tausinov @ Oct 18 2017, 15:18)  Пропускаем данные через блоки IDELAYE2, перебираем все возможные задержки. Засекаем две задержки - минимальную и максимальную, при которых тестовая последовательность или счетчик проходят тест. Берем ту, что по середине - попадаем на центр окна. Спасибо. Главное для себя узнал, поскольку практически во всех вариантах определения границ бита мы анализируем данные и на основании принятых данныех делаем вывод о границах бита. Я просто думал, может есть какая "хитрая" схема по типу фазового детектора, где мы не данные смотрим, а обнаруживаем сам факт изменения бита. На медленной скорости приема за счет какого-нибудь oversampling - это не проблема совсем. А вот на скоростях приёма, близких к предельным для ПЛИС, этот вариант не подходит.
Сообщение отредактировал Flip-fl0p - Oct 18 2017, 12:39
|
|
|
|
|
Oct 18 2017, 17:15
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 7-10-10
Пользователь №: 59 981

|
Сделал 2 различных варианта работы. Пробовал как в XAPP 524, так и и по XAPP585. В обоих документах калибровка начинается с "выравнивания" такта. Про данные позже. Вход защёлкнут IBUFGDS. Далее так идёт на IDELAY2, выходит задержанный сигнал, идёт на вход DDLY ISERDES. Выход, который О, раздваивается на IOBUF (нужен в качестве быстрого такта для ISERDESов) и на BUFR (делит на 4) и используеся в качестве делённой частоты, также идёт на ISERDESы. Выход ISERDES анализируется. Также отмечаю, что пробовал ещё несколько вариантов деления частоты, использования MMCM и др. Подстройку провожу с помощью C и CE на IDELAYE2. Совершенно не нравится, что результат не меняется или меняется на 1 отчёт, а потом восстанавливаеся. Поясню. В режиме защёлкивания такта DDR я всегда получаю значение 55. Если даю задержку (через VIO), то один такт получаю что-то типа 5E, а потом опять 55. Если ставлю SDR, то итоговое значение FF, которое также не меняется - хоть на СЕ всегда подавай 1.
Один из вариантов кода привожу ниже.
x_dco0 : IBUFGDS generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => TRUE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards IOSTANDARD => "LVDS_25") port map ( O => aclk, -- Clock buffer output I => dco1p, -- Diff_p clock buffer input (connect directly to top-level port) IB => dco1n -- 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", CINVCTRL_SEL => "FALSE", IDELAY_TYPE => "VARIABLE", IDELAY_VALUE => 0, PIPE_SEL => "FALSE" ) port map ( DATAIN => '0', IDATAIN => aclk, DATAOUT => d_aclk, C => aclk_div, CE => set_idelay_dco, INC => '1', LD => '0', CNTVALUEIN => "00000", CNTVALUEOUT => open,- REGRST => reset, CINVCTRL => '0', LDPIPEEN => '0' ); BUFR_ins1 : BUFR generic map ( BUFR_DIVIDE => "4", -- 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 => '0', -- 1-bit input: Active high, asynchronous clear (Divided modes only) I => IntBitClk -- 1-bit input: Clock buffer input driven by an IBUFG, MMCM or local interconnect );
xCLK_FB_inv: bufio port map ( i => IntBitClk, o => aclk_int ); --FB aclk_int_n<=not aclk_int; xISERDES111: ISERDESE2 generic map ( SERDES_MODE => "MASTER", INTERFACE_TYPE => "NETWORKING", IOBDELAY => "IBUF", DATA_RATE => "DDR", DATA_WIDTH => 8, 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 => dco_calib_out(4), Q6 => dco_calib_out(5), Q7 => dco_calib_out(6), Q8 => dco_calib_out(7), -- Unregistered output O => IntBitClk, --ser_dat(ii), -- Carry out for bit expansion SHIFTOUT1 => open, SHIFTOUT2 => open, -- Serial data in from PAD or IODELAY D => '0',-- aclk,--'0', DDLY => d_aclk,--d_aclk, -- Carry in for bit expansion SHIFTIN1 => '0', SHIFTIN2 => '0', -- Clock signals CLK => aclk_int,-- high-speed clock CLKB => aclk_int_n, -- inverted clock CLKDIV => aclk_div,-- divided clock -- Clock enable CE1 => '1', CE2 => '0', -- Reset RST => reset, --rst(i), --- NOT USED BITSLIP => '0', -- bitslip operation------------------- OCLK => '0', -- high-speed clock OCLKB => '0', -- inverted clock DYNCLKSEL => '0', DYNCLKDIVSEL => '0', CLKDIVP => '0', OFB => '0' -- feedback path
);
dco_calib_out_t<=dco_calib_out;
|
|
|
|
|
Oct 18 2017, 22:56
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 7-10-10
Пользователь №: 59 981

|
Цитата(Алга @ Oct 18 2017, 20:39)  Примитив IDELAYCTRL в системе заведен? Можно проверить работает ли IDELAYE2, увеличили значение задержки посмотрели на выходах CNTVALUEOUT код задержки. Все коды должны быть стабильны. В данной реализации НЕ заведён, но в ряде предыдущих был однозначно. Не могу сказать, что что-то изменилось после этого. Тем не менее, сегодня его вставлю, отпишусь. По поводу CNTVALUEOUT-вчера заводит длятеста IN (результат такой же, как и с инкрементом задержки на 1/32), OUT же оставил открытым, сегодня проверю. Спасибо!
|
|
|
|
|
Oct 19 2017, 05:34
|
Знающий
   
Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515

|
Цитата(Art55555 @ Oct 19 2017, 01:56)  В данной реализации НЕ заведён, но в ряде предыдущих был однозначно. Не могу сказать, что что-то изменилось после этого. Тем не менее, сегодня его вставлю, отпишусь.
По поводу CNTVALUEOUT-вчера заводит длятеста IN (результат такой же, как и с инкрементом задержки на 1/32), OUT же оставил открытым, сегодня проверю. Спасибо! Дизайн этот странный какой-то. Вы заводите на вход данных SERDES задержанный клок, и на вход клока SERDES тот же самый задержанный клок, естественно, изменение задержки не будет менять значения на выходах SERDES. И ещё непонятно, зачем пропускать клок через IBUFGDS(он же вроде BUFG вставляет) а потом ещё и через SERDES, а не прямо по цепочке IBUFDS -> IDELAY -> (BUFIO, BUFR параллельно)
|
|
|
|
|
Oct 19 2017, 07:56
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 7-10-10
Пользователь №: 59 981

|
Цитата(Timmy @ Oct 19 2017, 09:34)  Дизайн этот странный какой-то. Вы заводите на вход данных SERDES задержанный клок, и на вход клока SERDES тот же самый задержанный клок, естественно, изменение задержки не будет менять значения на выходах SERDES. И ещё непонятно, зачем пропускать клок через IBUFGDS(он же вроде BUFG вставляет) а потом ещё и через SERDES, а не прямо по цепочке IBUFDS -> IDELAY -> (BUFIO, BUFR параллельно) Это скрин от XAPP524, выход SERDES идёт на клоковые буферы, а при выходе из компонента сразу заводится на вход.
По поводу IBUFGDS. Такт приходит с клоковых ног, и из P и N я делаю общий глобальный клок. Или я что-то не так понимаю? )) В итоге, как подключать-то?
|
|
|
|
|
Oct 19 2017, 16:26
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 7-10-10
Пользователь №: 59 981

|
Учёл все рекомендации. Результат такой же. Сигнал dco_calib_out ВСЕГДА равен AA. Пробовал менять задержку через CNTVALUEIN - ничего не меняется. Если же пытаюсь подстраиваться через CE/INC, то на 1 такт АА превращается в BA. Не фиксируется. Код ниже.
x_dco0 : IBUFDS generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => TRUE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards IOSTANDARD => "LVDS_25") port map ( O => aclk, -- Clock buffer output I => dco1p, -- Diff_p clock buffer input (connect directly to top-level port) IB => dco1n -- 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", CINVCTRL_SEL => "FALSE", IDELAY_TYPE => "VARIABLE", IDELAY_VALUE => 0, PIPE_SEL => "FALSE" ) port map ( DATAIN => '0',--, IDATAIN => aclk, DATAOUT => d_aclk, C => CLK, CE => set_idelay_dco, INC => '1', LD => ld_dco_delay, CNTVALUEIN => dco_delay, CNTVALUEOUT => open, REGRST => reset, CINVCTRL => '0', LDPIPEEN => '0' ); bufio_adc: buf port map ( i => d_aclk, o => aclk_main ); --FB BUFR_ins1 : BUFR generic map ( BUFR_DIVIDE => "4", -- 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 => '0', -- 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, RST => reset, RDY => AdcIdlyCtrlRdy);
xISERDES111: ISERDESE2 generic map ( SERDES_MODE => "MASTER", INTERFACE_TYPE => "NETWORKING", IOBDELAY => "Both", DATA_RATE => "DDR", DATA_WIDTH => 8, 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 => dco_calib_out(4), Q6 => dco_calib_out(5), Q7 => dco_calib_out(6), Q8 => 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', DDLY => '0', --d_aclk,--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 => reset, --rst(i), --- NOT USED BITSLIP => '0', -- bitslip operation------------------- OCLK => '0', -- high-speed clock OCLKB => '0', -- inverted clock DYNCLKSEL => '0', DYNCLKDIVSEL => '0', CLKDIVP => '0', OFB => '0' -- feedback path
);
dco_calib_out_t<=dco_calib_out;
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|