Перейти к содержанию
    

Прием данных с АЦП AD9681

FRAME (frame clk) должен использоваться в любом случае.

Есть два варианта структурных схем соединения. Это xapp524 и xapp585.

Какой у вас непонятно. Важна и блок схема клок дистрибьюции.

Как формируются сигналы bitclk и frmclk для сердеса и тд?

Потом режим 12 бит АЦП как делается на сердесах? (xapp585, p.2)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

FRAME (frame clk) должен использоваться в любом случае.

Есть два варианта структурных схем соединения. Это xapp524 и xapp585.

Какой у вас непонятно. Важна и блок схема клок дистрибьюции.

Как формируются сигналы bitclk и frmclk для сердеса и тд?

Потом режим 12 бит АЦП как делается на сердесах? (xapp585, p.2)

Спасибо за эти Xapp, их я как раз не читал.

Я бегло просмотрел их, и как я понял если частоты bit clock и frame clock никак не связанны временным соотношением с данными (соотношение может быть любым и разным при каждом включении питания) то эти варианты неприменимы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня за основу принят xapp585. В системе 4 отдельных корпуса АЦП другого типа. Все работает.

Начинал с харр524, Казалось будет проще. Но в итоге отказался и перешел на xapp585.

 

Не заметил один из вопросов. Как определяются границы бита?

Принимаются данные через сердес и запоминаются Далее меняется задержка.

Но при очередной следующей задержке, если сменимись данные (код данных), то это означает что попали на фронт смены бита.

Так определяются границы задержек стабильного приема данных и вычисляется середина этого участка,

которая и окончательно устанавливается. Все это описано в xapp'ах и даже лучше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня за основу принят xapp585. В системе 4 отдельных корпуса АЦП другого типа. Все работает.

Начинал с харр524, Казалось будет проще. Но в итоге отказался и перешел на xapp585.

 

Не заметил один из вопросов. Как определяются границы бита?

Принимаются данные через сердес и запоминаются Далее меняется задержка.

Но при очередной следующей задержке, если сменимись данные (код данных), то это означает что попали на фронт смены бита.

Так определяются границы задержек стабильного приема данных и вычисляется середина этого участка,

которая и окончательно устанавливается. Все это описано в xapp'ах и даже лучше.

Понятно, я точно-так же и калибруюсь :bb-offtopic: .

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня за основу принят xapp585. В системе 4 отдельных корпуса АЦП другого типа. Все работает.

Начинал с харр524, Казалось будет проще. Но в итоге отказался и перешел на xapp585.

 

Не заметил один из вопросов. Как определяются границы бита?

Принимаются данные через сердес и запоминаются Далее меняется задержка.

Но при очередной следующей задержке, если сменимись данные (код данных), то это означает что попали на фронт смены бита.

Так определяются границы задержек стабильного приема данных и вычисляется середина этого участка,

которая и окончательно устанавливается. Все это описано в xapp'ах и даже лучше.

 

Отправил Вам в личку сообщение. Посмотрите, плз. Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А можно про этот процесс чуть подробнее ?

Допустим есть некий АЦП который управляется по SPI.

Мы либо запускаем АЦП в "нормальном" режиме - когда он гонит данные.

Либо запускаем АПЦ в режиме калибровки - когда он гонит тестовую последовательность.

Читал доки от xilinx но так и не понял как определяются границы бита, чтобы выставить клок в центр данных.

 

 

Пропускаем данные через блоки IDELAYE2, перебираем все возможные задержки. Засекаем две задержки - минимальную и максимальную, при которых тестовая последовательность или счетчик проходят тест. Берем ту, что по середине - попадаем на центр окна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пропускаем данные через блоки IDELAYE2, перебираем все возможные задержки. Засекаем две задержки - минимальную и максимальную, при которых тестовая последовательность или счетчик проходят тест. Берем ту, что по середине - попадаем на центр окна.

Спасибо. Главное для себя узнал, поскольку практически во всех вариантах определения границ бита мы анализируем данные и на основании принятых данныех делаем вывод о границах бита.

Я просто думал, может есть какая "хитрая" схема по типу фазового детектора, где мы не данные смотрим, а обнаруживаем сам факт изменения бита. На медленной скорости приема за счет какого-нибудь oversampling - это не проблема совсем. А вот на скоростях приёма, близких к предельным для ПЛИС, этот вариант не подходит.

Изменено пользователем Flip-fl0p

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сделал 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;

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Примитив IDELAYCTRL в системе заведен?

Можно проверить работает ли IDELAYE2,

увеличили значение задержки посмотрели на выходах CNTVALUEOUT код задержки. Все коды должны быть стабильны.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Примитив IDELAYCTRL в системе заведен?

Можно проверить работает ли IDELAYE2,

увеличили значение задержки посмотрели на выходах CNTVALUEOUT код задержки. Все коды должны быть стабильны.

 

В данной реализации НЕ заведён, но в ряде предыдущих был однозначно. Не могу сказать, что что-то изменилось после этого. Тем не менее, сегодня его вставлю, отпишусь.

 

По поводу CNTVALUEOUT-вчера заводит длятеста IN (результат такой же, как и с инкрементом задержки на 1/32), OUT же оставил открытым, сегодня проверю.

Спасибо!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В данной реализации НЕ заведён, но в ряде предыдущих был однозначно. Не могу сказать, что что-то изменилось после этого. Тем не менее, сегодня его вставлю, отпишусь.

 

По поводу CNTVALUEOUT-вчера заводит длятеста IN (результат такой же, как и с инкрементом задержки на 1/32), OUT же оставил открытым, сегодня проверю.

Спасибо!

Дизайн этот странный какой-то. Вы заводите на вход данных SERDES задержанный клок, и на вход клока SERDES тот же самый задержанный клок, естественно, изменение задержки не будет менять значения на выходах SERDES. И ещё непонятно, зачем пропускать клок через IBUFGDS(он же вроде BUFG вставляет) а потом ещё и через SERDES, а не прямо по цепочке IBUFDS -> IDELAY -> (BUFIO, BUFR параллельно)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Напомню, что к xapp524,585 есть исходники как пример (как и к другим xapp'ам). Можно скачать и посмотреть.

Также история вопроса (идеи) начинается с xapp855,856,860, 774, 1064 по мере появления новых семейств.

В том смысле что примеры более простые.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дизайн этот странный какой-то. Вы заводите на вход данных SERDES задержанный клок, и на вход клока SERDES тот же самый задержанный клок, естественно, изменение задержки не будет менять значения на выходах SERDES. И ещё непонятно, зачем пропускать клок через IBUFGDS(он же вроде BUFG вставляет) а потом ещё и через SERDES, а не прямо по цепочке IBUFDS -> IDELAY -> (BUFIO, BUFR параллельно)

 

 

Это скрин от XAPP524, выход SERDES идёт на клоковые буферы, а при выходе из компонента сразу заводится на вход.

post-59981-1508399275_thumb.jpg

 

По поводу IBUFGDS. Такт приходит с клоковых ног, и из P и N я делаю общий глобальный клок. Или я что-то не так понимаю? ))

 

В итоге, как подключать-то?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Надо пока доверять xapp'у (исходникам) и проверять.

В скрин не попали аттрибуты SERDESE2, важно состояние аттрибута IOBDELAY= (NONE,IBUF,IFD, BOTH),

ug471, p.157. Тогда на выходах SERDESE2 разная ситуация.

На фиг6 xapp'a неточность.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Учёл все рекомендации.

Результат такой же.

Сигнал 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;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...