Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LVDS преобразователь
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
EpLeon
Добрый день.

Подскажите, пожалуйста. Задача заключается в следующем: есть 10-битный АЦП AD9212 - он посылает данные в формате LVDS с частотой 400Mbps или 40МГц на событие. Необходимо рсшифровать эти данные в Циклоне - EP4CE55F23C6. Пробую использовать встроенную мегафункцию altlvds_rx со следующими параметрами:
SUBDESIGN LVDS_In
(
rx_in[0..0] : INPUT;
rx_inclock : INPUT = GND;
rx_locked : OUTPUT;
rx_out[9..0] : OUTPUT;
rx_outclock : OUTPUT;
)
VARIABLE
altlvds_rx_component : altlvds_rx WITH (
COMMON_RX_TX_PLL = "ON",
DESERIALIZATION_FACTOR = 10,
IMPLEMENT_IN_LES = "ON",
INCLOCK_DATA_ALIGNMENT = "UNUSED",
INCLOCK_PERIOD = 25000,
INCLOCK_PHASE_SHIFT = 0,
INPUT_DATA_RATE = 400,
INTENDED_DEVICE_FAMILY = "Cyclone IV E",
LPM_HINT = "CBX_MODULE_PREFIX=LVDS_In",
LPM_TYPE = "altlvds_rx",
NUMBER_OF_CHANNELS = 1,
PLL_SELF_RESET_ON_LOSS_LOCK = "OFF",
PORT_RX_CHANNEL_DATA_ALIGN = "PORT_UNUSED",
PORT_RX_DATA_ALIGN = "PORT_UNUSED",
REGISTERED_DATA_ALIGN_INPUT = "OFF",
REGISTERED_OUTPUT = "ON",
USE_EXTERNAL_PLL = "OFF"
);
BEGIN

rx_locked = altlvds_rx_component.rx_locked;
rx_out[9..0] = altlvds_rx_component.rx_out[9..0];
rx_outclock = altlvds_rx_component.rx_outclock;
altlvds_rx_component.rx_inclock = rx_inclock;
altlvds_rx_component.rx_in[0..0] = rx_in[0..0];
END;

Пишу на языке AHDL в силу пока незнания остальных. Данные, которые потом вывожу на ножки циклона в виде параллельного кода как-то не соответствуют сигналу. Подскажите, все ли правильно в настройка функции. Клок на функцию использую тот же, что и в самой альтере для других вещей через pll функцию. Сама же частота задается извне генератором 40МГц.
iiv
Цитата(EpLeon @ Mar 2 2016, 10:32) *
rx_inclock : INPUT = GND;

это же клок фрейма (FCO+,FCO-), который в Вашем случае в 10 раз медленнее клока данных. Вам также надо прописать правильные частоты, на который Вы будете работать, чтобы altlvds сделало на своей PLL такт для данных, оно у Вас есть, и вроде правильное (DESERIALIZATION_FACTOR = 10, INPUT_DATA_RATE = 400).

Кстати, в этом случае, клок данных (DCO+, DCO-) получается не нужен и это очень странно. Вот в этом последнем утверждении сам сомневаюсь, очень надеюсь, что кто-то поправит, если я ошибаюсь.
doom13
Цитата(iiv @ Mar 2 2016, 11:42) *
это же клок фрейма (FCO+,FCO-), который в Вашем случае в 10 раз медленнее клока данных.
Кстати, в этом случае, клок данных (DCO+, DCO-) получается не нужен и это очень странно. Вот в этом последнем утверждении сам сомневаюсь, очень надеюсь, что кто-то поправит, если я ошибаюсь.

На порт rx_inclock может подаваться как frame clock, так и data clock, просто необходимо задать правильные параметры для ядра.
doom13
Цитата(EpLeon @ Mar 2 2016, 08:32) *
Добрый день.

Подскажите, пожалуйста. Задача заключается в следующем: есть 10-битный АЦП AD9212 - он посылает данные в формате LVDS с частотой 400Mbps или 40МГц на событие. Необходимо рсшифровать эти данные в Циклоне - EP4CE55F23C6. Пробую использовать встроенную мегафункцию altlvds_rx со следующими параметрами:

Пишу на языке AHDL в силу пока незнания остальных. Данные, которые потом вывожу на ножки циклона в виде параллельного кода как-то не соответствуют сигналу. Подскажите, все ли правильно в настройка функции. Клок на функцию использую тот же, что и в самой альтере для других вещей через pll функцию. Сама же частота задается извне генератором 40МГц.


Параметры ядра у Вас заданы неправильно. Скорость потока данных 400 Mbit/s, а тактовая 200 MHz (40MHz * 5 = 200 MHz) - приёмник должен принимать DDR поток данных.

INCLOCK_PERIOD = 5000
EpLeon
Цитата(doom13 @ Mar 2 2016, 20:28) *
Параметры ядра у Вас заданы неправильно. Скорость потока данных 400 Mbit/s, а тактовая 200 MHz (40MHz * 5 = 200 MHz) - приёмник должен принимать DDR поток данных.

Немного не понял по поводу тактовой скорости. Почему она должна быть 200МГц, а не 40? У меня частота АЦП 40МГц = 25нс, за эти 25нс он передает 10 бит данных. То есть 400Мб/с. Может быть тогда уж 800МГц? Но не 200... он же будет два бита схлопывать, как один...
doom13
Цитата(EpLeon @ Mar 2 2016, 17:40) *
Немного не понял по поводу тактовой скорости. Почему она должна быть 200МГц, а не 40? У меня частота АЦП 40МГц = 25нс, за эти 25нс он передает 10 бит данных. То есть 400Мб/с. Может быть тогда уж 800МГц? Но не 200... он же будет два бита схлопывать, как один...

Да, ступил, если frame clock подаёте на ногу ядра, то всё правильно.

PS:
Имел ввиду, что для тактирования ядра используется data clock, а он в Вашем случае 200 MHz, работает по двум фронтам (см. доку).

Цитата(EpLeon @ Mar 2 2016, 08:32) *
Клок на функцию использую тот же, что и в самой альтере для других вещей через pll функцию. Сама же частота задается извне генератором 40МГц.

Что это означает? Ядро ALTLVDS_RX должно тактироваться "клоком" от АЦП (fclk или dclk).
doom13
Ещё разберитесь с
Цитата
PORT_RX_CHANNEL_DATA_ALIGN = "PORT_UNUSED",
PORT_RX_DATA_ALIGN = "PORT_UNUSED",
REGISTERED_DATA_ALIGN_INPUT = "OFF",
, вероятно, последовательные данные принимаются со сдвигом на N-бит. Тут необходим автомат который будет находить границы принимаемого слова.
EpLeon
Цитата(doom13 @ Mar 2 2016, 22:12) *
Ещё разберитесь с
, вероятно, последовательные данные принимаются со сдвигом на N-бит. Тут необходим автомат который будет находить границы принимаемого слова.

Но из АЦП не выходит каких либо служебных сигналов - только данные и есть еще две пары ножек с тактовыми частотами FCO и DCO.
Кроме того, если я правильно понимаю, то у меня функция циклона тактируется сама - внешний клок у нее отключен USE_EXTERNAL_PLL = "OFF".
EpLeon
Цитата(doom13 @ Mar 2 2016, 21:06) *
Да, ступил, если frame clock подаёте на ногу ядра, то всё правильно.

PS:
Имел ввиду, что для тактирования ядра используется data clock, а он в Вашем случае 200 MHz, работает по двум фронтам (см. доку).


Что это означает? Ядро ALTLVDS_RX должно тактироваться "клоком" от АЦП (fclk или dclk).


То есть я правильно понимаю, что мне нужно взять с АЦП FCO и DCO и по ним тактировать данные с АЦП? Первым тактировать посылки, а вторым сами биты в посылке? Но когда я пытаюсь создать в мегофункции внешний клок, то Квартус ругается, что максимальная частота для внешнего тактирования 760МГц, так как ему нужна в данном случае удвоенная частота прихода бит.
doom13
Цитата(EpLeon @ Mar 3 2016, 02:48) *
Но из АЦП не выходит каких либо служебных сигналов - только данные и есть еще две пары ножек с тактовыми частотами FCO и DCO.

Есть ещё SPI, который позволяет переключить АЦП в режим синхронизации, когда на выход выдаётся test pattern. Он используется для определения правильных границ принимаемого слова (совместно с align портом ядра).

Цитата(EpLeon @ Mar 3 2016, 02:48) *
Кроме того, если я правильно понимаю, то у меня функция циклона тактируется сама - внешний клок у нее отключен USE_EXTERNAL_PLL = "OFF".

ALTLVDS_RX должна тактироваться от FCO или DCO (лучше DCO). USE_EXTERNAL_PLL = "OFF" - означает, что ядро ALTLVDS_RX будет использовать PLL внутри, который сгенерирует все необходимые для работы ядра клоки. Можно включить опцию "ON" (внешний PLL), чтобы была возможность использовать данный PLL для тактирования других модулей.

Цитата(EpLeon @ Mar 3 2016, 08:52) *
То есть я правильно понимаю, что мне нужно взять с АЦП FCO и DCO и по ним тактировать данные с АЦП? Первым тактировать посылки, а вторым сами биты в посылке? Но когда я пытаюсь создать в мегофункции внешний клок, то Квартус ругается, что максимальная частота для внешнего тактирования 760МГц, так как ему нужна в данном случае удвоенная частота прихода бит.

На rx_inclock подаёте DCO, ядро настраиваете следующим образом (для приёма одного канала АЦП):
CODE

ALTLVDS_RX_component.buffer_implementation = "RAM",
ALTLVDS_RX_component.cds_mode = "UNUSED",
ALTLVDS_RX_component.common_rx_tx_pll = "OFF",
ALTLVDS_RX_component.data_align_rollover = 4,
ALTLVDS_RX_component.data_rate = "400.0 Mbps",
ALTLVDS_RX_component.deserialization_factor = 10,
ALTLVDS_RX_component.dpa_initial_phase_value = 0,
ALTLVDS_RX_component.dpll_lock_count = 0,
ALTLVDS_RX_component.dpll_lock_window = 0,
ALTLVDS_RX_component.enable_clock_pin_mode = "UNUSED",
ALTLVDS_RX_component.enable_dpa_align_to_rising_edge_only = "OFF",
ALTLVDS_RX_component.enable_dpa_calibration = "ON",
ALTLVDS_RX_component.enable_dpa_fifo = "UNUSED",
ALTLVDS_RX_component.enable_dpa_initial_phase_selection = "OFF",
ALTLVDS_RX_component.enable_dpa_mode = "OFF",
ALTLVDS_RX_component.enable_dpa_pll_calibration = "OFF",
ALTLVDS_RX_component.enable_soft_cdr_mode = "OFF",
ALTLVDS_RX_component.implement_in_les = "OFF",
ALTLVDS_RX_component.inclock_boost = 0,
ALTLVDS_RX_component.inclock_data_alignment = "EDGE_ALIGNED",
ALTLVDS_RX_component.inclock_period = 5000,
ALTLVDS_RX_component.inclock_phase_shift = 0,
ALTLVDS_RX_component.input_data_rate = 400,
ALTLVDS_RX_component.intended_device_family = "Cyclone V",
ALTLVDS_RX_component.lose_lock_on_one_change = "UNUSED",
ALTLVDS_RX_component.lpm_hint = "CBX_MODULE_PREFIX=ghh",
ALTLVDS_RX_component.lpm_type = "altlvds_rx",
ALTLVDS_RX_component.number_of_channels = 1,
ALTLVDS_RX_component.outclock_resource = "Dual-Regional clock",
ALTLVDS_RX_component.pll_operation_mode = "NORMAL",
ALTLVDS_RX_component.pll_self_reset_on_loss_lock = "UNUSED",
ALTLVDS_RX_component.port_rx_channel_data_align = "PORT_UNUSED",
ALTLVDS_RX_component.port_rx_data_align = "PORT_UNUSED",
ALTLVDS_RX_component.refclk_frequency = "200.000000 MHz",
ALTLVDS_RX_component.registered_data_align_input = "UNUSED",
ALTLVDS_RX_component.registered_output = "ON",
ALTLVDS_RX_component.reset_fifo_at_first_lock = "UNUSED",
ALTLVDS_RX_component.rx_align_data_reg = "RISING_EDGE",
ALTLVDS_RX_component.sim_dpa_is_negative_ppm_drift = "OFF",
ALTLVDS_RX_component.sim_dpa_net_ppm_variation = 0,
ALTLVDS_RX_component.sim_dpa_output_clock_phase_shift = 0,
ALTLVDS_RX_component.use_coreclock_input = "OFF",
ALTLVDS_RX_component.use_dpll_rawperror = "OFF",
ALTLVDS_RX_component.use_external_pll = "OFF",
ALTLVDS_RX_component.use_no_phase_shift = "ON",
ALTLVDS_RX_component.x_on_bitslip = "ON",
ALTLVDS_RX_component.clk_src_is_pll = "off";


PS:
Если принять правильные данные не удаётся - добавляете rx_channel_data_align порт и реализуете автомат синхронизации.
iiv
Цитата(doom13 @ Mar 3 2016, 11:40) *
ALTLVDS_RX должна тактироваться от FCO или DCO (лучше DCO).

скажите, пожалуйста, можно ли тактировать АЦПшку от DCO, но использовать FCO для распознания начала фрейма, и, если да, то как? Иначе как-то не логично получается, нога есть, а пользы от нее нет.
EpLeon
Цитата(doom13 @ Mar 3 2016, 12:40) *
Есть ещё SPI, который позволяет переключить АЦП в режим синхронизации, когда на выход выдаётся test pattern. Он используется для определения правильных границ принимаемого слова (совместно с align портом ядра).


ALTLVDS_RX должна тактироваться от FCO или DCO (лучше DCO). USE_EXTERNAL_PLL = "OFF" - означает, что ядро ALTLVDS_RX будет использовать PLL внутри, который сгенерирует все необходимые для работы ядра клоки. Можно включить опцию "ON" (внешний PLL), чтобы была возможность использовать данный PLL для тактирования других модулей.


На rx_inclock подаёте DCO, ядро настраиваете следующим образом (для приёма одного канала АЦП):
CODE

ALTLVDS_RX_component.buffer_implementation = "RAM",
ALTLVDS_RX_component.cds_mode = "UNUSED",
ALTLVDS_RX_component.common_rx_tx_pll = "OFF",
ALTLVDS_RX_component.data_align_rollover = 4,
ALTLVDS_RX_component.data_rate = "400.0 Mbps",
ALTLVDS_RX_component.deserialization_factor = 10,
ALTLVDS_RX_component.dpa_initial_phase_value = 0,
ALTLVDS_RX_component.dpll_lock_count = 0,
ALTLVDS_RX_component.dpll_lock_window = 0,
ALTLVDS_RX_component.enable_clock_pin_mode = "UNUSED",
ALTLVDS_RX_component.enable_dpa_align_to_rising_edge_only = "OFF",
ALTLVDS_RX_component.enable_dpa_calibration = "ON",
ALTLVDS_RX_component.enable_dpa_fifo = "UNUSED",
ALTLVDS_RX_component.enable_dpa_initial_phase_selection = "OFF",
ALTLVDS_RX_component.enable_dpa_mode = "OFF",
ALTLVDS_RX_component.enable_dpa_pll_calibration = "OFF",
ALTLVDS_RX_component.enable_soft_cdr_mode = "OFF",
ALTLVDS_RX_component.implement_in_les = "OFF",
ALTLVDS_RX_component.inclock_boost = 0,
ALTLVDS_RX_component.inclock_data_alignment = "EDGE_ALIGNED",
ALTLVDS_RX_component.inclock_period = 5000,
ALTLVDS_RX_component.inclock_phase_shift = 0,
ALTLVDS_RX_component.input_data_rate = 400,
ALTLVDS_RX_component.intended_device_family = "Cyclone V",
ALTLVDS_RX_component.lose_lock_on_one_change = "UNUSED",
ALTLVDS_RX_component.lpm_hint = "CBX_MODULE_PREFIX=ghh",
ALTLVDS_RX_component.lpm_type = "altlvds_rx",
ALTLVDS_RX_component.number_of_channels = 1,
ALTLVDS_RX_component.outclock_resource = "Dual-Regional clock",
ALTLVDS_RX_component.pll_operation_mode = "NORMAL",
ALTLVDS_RX_component.pll_self_reset_on_loss_lock = "UNUSED",
ALTLVDS_RX_component.port_rx_channel_data_align = "PORT_UNUSED",
ALTLVDS_RX_component.port_rx_data_align = "PORT_UNUSED",
ALTLVDS_RX_component.refclk_frequency = "200.000000 MHz",
ALTLVDS_RX_component.registered_data_align_input = "UNUSED",
ALTLVDS_RX_component.registered_output = "ON",
ALTLVDS_RX_component.reset_fifo_at_first_lock = "UNUSED",
ALTLVDS_RX_component.rx_align_data_reg = "RISING_EDGE",
ALTLVDS_RX_component.sim_dpa_is_negative_ppm_drift = "OFF",
ALTLVDS_RX_component.sim_dpa_net_ppm_variation = 0,
ALTLVDS_RX_component.sim_dpa_output_clock_phase_shift = 0,
ALTLVDS_RX_component.use_coreclock_input = "OFF",
ALTLVDS_RX_component.use_dpll_rawperror = "OFF",
ALTLVDS_RX_component.use_external_pll = "OFF",
ALTLVDS_RX_component.use_no_phase_shift = "ON",
ALTLVDS_RX_component.x_on_bitslip = "ON",
ALTLVDS_RX_component.clk_src_is_pll = "off";


PS:
Если принять правильные данные не удаётся - добавляете rx_channel_data_align порт и реализуете автомат синхронизации.


Так и не понял почему у вас стоит 200МГц... хотя на DCO именно она и выходит - проверил щупом. При этом частоты внутри циклона и АЦП синхрованы, поэтому не очень понятно зачем использовать FCO? Кроме того вопрос можно ли обойтись без FCO и DCO? Просто АЦП и циклон находятся на разных платах и возможности их соединить еще одним кабельком очевидной нет( И таких платок с АЦП у меня две и они обе соединяются с циклоном.

И еще. У меня установлен квартус 9.1 в нем мегофункция приемника немного попроще. И пишу я на AHDL. Вверху топика я привел параметры мегофункции, которые у меня сейчас установлены.
doom13
Цитата(iiv @ Mar 3 2016, 10:55) *
скажите, пожалуйста, можно ли тактировать АЦПшку от DCO, но использовать FCO для распознания начала фрейма, и, если да, то как? Иначе как-то не логично получается, нога есть, а пользы от нее нет.

Тактовая частота АЦП и FCO равны (в МГц). Для тактирования приёмника можно использовать как FCO, так и DCO (одну из них, лучше DCO), ядро ALTLVDS_RX поставит внутри PLL и само сгенерирует необходимые клоки, или можно задать вручную при использовании внешнего PLL. Правильный приём фрейма осуществляется синхронизацией АЦП и приёмника (используется порт rx_data_align).

Цитата(EpLeon @ Mar 3 2016, 11:09) *
Так и не понял почему у вас стоит 200МГц... хотя на DCO именно она и выходит - проверил щупом. При этом частоты внутри циклона и АЦП синхрованы, поэтому не очень понятно зачем использовать FCO? Кроме того вопрос можно ли обойтись без FCO и DCO? Просто АЦП и циклон находятся на разных платах и возможности их соединить еще одним кабельком очевидной нет( И таких платок с АЦП у меня две и они обе соединяются с циклоном.

FCO - соответствует началу фрейма, Ваш синхронный клок будет сдвинут по фазе. Можно попробовать обойтись без FCO/DCO (так не делали), но без автомата, который ищет границы фрейма НЕТ (для этого случая Ваши настройки ядра верны).
iiv
Цитата(doom13 @ Mar 3 2016, 15:03) *
Тактовая частота АЦП и FCO равны (в МГц). Для тактирования приёмника можно использовать как FCO, так и DCO (одну из них, лучше DCO), ядро ALTLVDS_RX поставит внутри PLL и само сгенерирует необходимые клоки, или можно задать вручную при использовании внешнего PLL. Правильный приём фрейма осуществляется синхронизацией АЦП и приёмника (используется порт rx_data_align).

то есть, скажите, пожалуйста, правильно ли я понимаю, что надо DCO завести на rx_inclock, а FCO завести на rx_data_align?
doom13
Цитата(iiv @ Mar 3 2016, 13:18) *
то есть, скажите, пожалуйста, правильно ли я понимаю, что надо DCO завести на rx_inclock, а FCO завести на rx_data_align?

Это "стёб"?

Это правильно:
Цитата(iiv @ Mar 3 2016, 13:18) *
то есть, скажите, пожалуйста, правильно ли я понимаю, что надо DCO завести на rx_inclock...


Это нет:
Цитата(iiv @ Mar 3 2016, 13:18) *
а FCO завести на rx_data_align?

Каждый такт на rx_data_align сдвигает последовательность бит в выходных данных на 1 бит (т.о. сравниваем с ADC test pattern и ищем правильные границы фрейма).
EpLeon
Цитата(doom13 @ Mar 3 2016, 16:03) *
Тактовая частота АЦП и FCO равны (в МГц). Для тактирования приёмника можно использовать как FCO, так и DCO (одну из них, лучше DCO), ядро ALTLVDS_RX поставит внутри PLL и само сгенерирует необходимые клоки, или можно задать вручную при использовании внешнего PLL. Правильный приём фрейма осуществляется синхронизацией АЦП и приёмника (используется порт rx_data_align).


FCO - соответствует началу фрейма, Ваш синхронный клок будет сдвинут по фазе. Можно попробовать обойтись без FCO/DCO (так не делали), но без автомата, который ищет границы фрейма НЕТ (для этого случая Ваши настройки ядра верны).


Спасибо за разъяснения. Но, извините, не могли бы вы более детально пояснить, что в данной ситуации можно было бы сделать, чтобы данные виделись правильно (что изменить в настройках мегафункции и какие куда следовало бы подключать сигналы от АЦП и внутри циклона). Я с диф.сигналами и последовательным кодом никогда не работал. И не очень представляю/понимаю, как программировать по SPI этот АЦП.
Может быть есть небольшое недопонимание в плане работы самой платы:
Есть две маленькие платки, на которых распаяны АЦП. Они воткнуты через разъем в большую плату, которая должна получить с них данные, обработать и передать обработанную информацию на следующую плату, от которой она в свою очередь для синхронной работы в общей системе получает клок.
Поэтому мне не очень понятно, как я на ядро циклона могу подать сразу несколько клоков. Проблема заключается еще в том, что платы уже распаяны и сейчас идет процесс отладки/тестирования.
Если я правильно понимаю, то синхронность фрейма я могу увидеть по осциллографу - сдвинут ли один сигнал относительно другого. И кроме того мне не сильно важно на сколько задерживается сам фрейм с 10-ю битами. Мне главное, чтобы биты были правильно распакованы. А на данный момент выходит какая-то непонятность - не зависимо от амплитуды всегда ВСЕ биты скачут (я вывожу их в параллель на тестовые ноги).
doom13
Цитата(EpLeon @ Mar 3 2016, 15:00) *
Спасибо за разъяснения. Но, извините, не могли бы вы более детально пояснить, что в данной ситуации можно было бы сделать, чтобы данные виделись правильно (что изменить в настройках мегафункции и какие куда следовало бы подключать сигналы от АЦП и внутри циклона). Я с диф.сигналами и последовательным кодом никогда не работал. И не очень представляю/понимаю, как программировать по SPI этот АЦП.
Может быть есть небольшое недопонимание в плане работы самой платы:
Есть две маленькие платки, на которых распаяны АЦП. Они воткнуты через разъем в большую плату, которая должна получить с них данные, обработать и передать обработанную информацию на следующую плату, от которой она в свою очередь для синхронной работы в общей системе получает клок.
Поэтому мне не очень понятно, как я на ядро циклона могу подать сразу несколько клоков. Проблема заключается еще в том, что платы уже распаяны и сейчас идет процесс отладки/тестирования.
Если я правильно понимаю, то синхронность фрейма я могу увидеть по осциллографу - сдвинут ли один сигнал относительно другого. И кроме того мне не сильно важно на сколько задерживается сам фрейм с 10-ю битами. Мне главное, чтобы биты были правильно распакованы. А на данный момент выходит какая-то непонятность - не зависимо от амплитуды всегда ВСЕ биты скачут (я вывожу их в параллель на тестовые ноги).

Всё скачет, т.к. порядок бит в принимаемом слове неправильный. Идеальный вариант - завести диффпару DCO+/DCO- на Cyclone и на ALTLVDS_RX in_clock (это не отменяет необходимость автомата для синхронизации). Если возможности нет или очень сложно, то можно попытаться принять правильные данные на Вашей системе, для этого:
1) Разберитесь с чтением/записью регистров АЦП по SPI;
2) Переключаете АЦП в режим тестовой последовательности, передаваться будет известная последовательность;
3) Сделайте автомат, который будет тактировать порт rx_channel_data_align[n-1:0], если принятое слово не соответствует образцу;
4) Когда границы фрейма найдены, переключаете АЦП в нормальный режим работы.

PS
Как вариант - можно попробовать угадать, какой битовый сдвиг для принимаемого слова использовать, но - плохой вариант.
EpLeon
Цитата(doom13 @ Mar 3 2016, 18:46) *
Всё скачет, т.к. порядок бит в принимаемом слове неправильный. Идеальный вариант - завести диффпару DCO+/DCO- на Cyclone и на ALTLVDS_RX in_clock (это не отменяет необходимость автомата для синхронизации). Если возможности нет или очень сложно, то можно попытаться принять правильные данные на Вашей системе, для этого:
1) Разберитесь с чтением/записью регистров АЦП по SPI;
2) Переключаете АЦП в режим тестовой последовательности, передаваться будет известная последовательность;
3) Сделайте автомат, который будет тактировать порт rx_channel_data_align[n-1:0], если принятое слово не соответствует образцу;
4) Когда границы фрейма найдены, переключаете АЦП в нормальный режим работы.

PS
Как вариант - можно попробовать угадать, какой битовый сдвиг для принимаемого слова использовать, но - плохой вариант.


Не очень понял по поводу идеального варианта - завести диффпару DCO+/DCO- на Cyclone и на ALTLVDS_RX in_clock (это не отменяет необходимость автомата для синхронизации). То есть мне нужно DCO+/DCO- ввести в Cyclone на LVDS-ные ноги и в коде подключить на ALTLVDS_RX.in_clock? Но ведь в таком случае у меня буду появляться биты каждые 2.5нс, а не цельное 10-ти битовое слово каждые 25нс? И как можно его синхронизовать?
Если вам не сложно, пожалуйста, не могли бы вы подправить настройки, которые я выложил в первом сообщении в теме?
doom13
Цитата(EpLeon @ Mar 3 2016, 16:12) *
То есть мне нужно DCO+/DCO- ввести в Cyclone на LVDS-ные ноги и в
коде подключить на ALTLVDS_RX.in_clock? Но ведь в таком случае у меня буду появляться биты каждые 2.5нс, а не цельное 10-ти битовое
слово каждые 25нс? И как можно его синхронизовать?

Это идеальный вариант, выше по пунктам расписано, что необходимо сделать, чтобы система смогла работать в том виде, в каком есть сейчас.
Ещё доку на ядро почитайте, там расписан алгоритм работы.

Цитата(EpLeon @ Mar 3 2016, 16:12) *
Если вам не сложно, пожалуйста, не могли бы вы подправить настройки, которые я выложил в первом сообщении в теме?

Там всё правильно (для случая использования FCO или синхронного ему клока), только необходима синхронизация или вариант с гаданием правильного битового сдвига (тактируете align порт кнопкой или ещё каким способом и проверяете результат).
EpLeon
Цитата(doom13 @ Mar 3 2016, 19:39) *
Это идеальный вариант, выше по пунктам расписано, что необходимо сделать, чтобы система смогла работать в том виде, в каком есть сейчас.
Ещё доку на ядро почитайте, там расписан алгоритм работы.

Извини, но я все время путаюсь, что вы имеете в виду под словом "ядро".

Цитата(doom13 @ Mar 3 2016, 19:39) *
Там всё правильно (для случая использования FCO или синхронного ему клока), только необходима синхронизация или вариант с гаданием правильного битового сдвига (тактируете align порт кнопкой или ещё каким способом и проверяете результат).

Немного запутался... а синхронизация происходит не по FCO - синхронизация фрейма? Он же 40МГц? Если он тактируется фреймом, то защелкивать же должен синхронно с фреймом? Или это не так? И не очень понятно как расписывать align порт.
doom13
Цитата(EpLeon @ Mar 3 2016, 17:30) *
Извини, но я все время путаюсь, что вы имеете в виду под словом "ядро".

ALTLVDS_RX


Цитата(EpLeon @ Mar 3 2016, 17:30) *
Немного запутался... а синхронизация происходит не по FCO - синхронизация фрейма? Он же 40МГц? Если он тактируется фреймом, то защелкивать же должен синхронно с фреймом? Или это не так? И не очень понятно как расписывать align порт.

Читайте доку.
EpLeon
Цитата(doom13 @ Mar 3 2016, 19:39) *
Это идеальный вариант, выше по пунктам расписано, что необходимо сделать, чтобы система смогла работать в том виде, в каком есть сейчас.
Ещё доку на ядро почитайте, там расписан алгоритм работы.

Там всё правильно (для случая использования FCO или синхронного ему клока), только необходима синхронизация или вариант с гаданием правильного битового сдвига (тактируете align порт кнопкой или ещё каким способом и проверяете результат).


То есть я правильно понимаю, что ножка rx_data_align сдвигает на нужное количество бит сам фрейм, чтобы он правильно защелкнуться? Или не так? И я могу его попробовать подобрать сам, так как там всего 10 бит. Есть небольшой проблем - плату нужно запустить край через 3 дня(.
doom13
Цитата(EpLeon @ Mar 4 2016, 01:53) *
То есть я правильно понимаю, что ножка rx_data_align сдвигает на нужное количество бит сам фрейм, чтобы он правильно защелкнуться?

Да.
Цитата(EpLeon @ Mar 4 2016, 01:53) *
И я могу его попробовать подобрать сам, так как там всего 10 бит. Есть небольшой проблем - плату нужно запустить край через 3 дня(.

Можно попробовать (вручную тактировать align и анализировать принимаемые данные). Для одного канала, возможно, будет быстрее, чем полностью со всем разобраться и сделать правильно. Каналов АЦП 8 - пробуйте.
EpLeon
Цитата(doom13 @ Mar 4 2016, 12:32) *
Да.

Можно попробовать (вручную тактировать align и анализировать принимаемые данные). Для одного канала, возможно, будет быстрее, чем полностью со всем разобраться и сделать правильно. Каналов АЦП 8 - пробуйте.


Сдвиг происходит, просто задержкой зашелкивания по фазе? Я правильно понимаю, что на ножку align нужно подавать частоту фрейма и сдвигать по одному битику? И еще вопрос - будут ли все каналы синхронны? Или для каждого нужна отдельная тактировка?
doom13
Цитата(EpLeon @ Mar 4 2016, 18:51) *
Сдвиг происходит, просто задержкой зашелкивания по фазе? Я правильно понимаю, что на ножку align нужно подавать частоту фрейма и сдвигать по одному битику? И еще вопрос - будут ли все каналы синхронны? Или для каждого нужна отдельная тактировка?

Импульс на линии align даёт сдвиг фрейма на 1 бит. Каждый канал необходимо синхронизировать отдельно.
EpLeon
Цитата(doom13 @ Mar 5 2016, 03:51) *
Импульс на линии align даёт сдвиг фрейма на 1 бит. Каждый канал необходимо синхронизировать отдельно.


И еще, может быть, конечно и глупый вопрос, но для окончательного понимания и осознания - на align подается частота фрейма, которая и будет сдвигаться на один бить по фазе, то есть та же частота, что и на rx_inclock, только со сдвигом?
doom13
Цитата(EpLeon @ Mar 5 2016, 02:14) *
И еще, может быть, конечно и глупый вопрос, но для окончательного понимания и осознания - на align подается частота фрейма, которая и будет сдвигаться на один бить по фазе, то есть та же частота, что и на rx_inclock, только со сдвигом?

Из доки на ALTLVDS:
Цитата
Use ‘rx_channel_data_align’ input port

Turn on this option to control bit insertion on a channel-by-channel basis
to align the word boundaries of the incoming data. The data slips one bit
for every pulse on the rx_channel_data_align port. This option is
available only if you use a dedicated SERDES block.
You can use control characters in the data stream so your logic can have
a known pattern to search for. You can compare the data received for
each channel, compare to the control character you are looking for, then
pulse the rx_channel_data_align port as required until you
successfully receive the control character.
To use this port, you must meet the following requirements:
■ The minimum pulse width is one period of the parallel clock in the
logic array (rx_outclock).
■ The minimum low time between pulses is one period of the parallel
clock.
■ There is no maximum high or low time.
■ Valid data is available two parallel clock cycles after the rising edge of
rx_channel_data_align signal.
EpLeon
Цитата(doom13 @ Mar 5 2016, 13:11) *
Из доки на ALTLVDS:

Честно говоря, прочитав данный текст, я только больше запутался... на align нужно подавать клок со сдвигом по фазе, в зависимости от того на сколько бит сдвинуть - на столько и задерживать фазу данного клока, или нет?
_Anatoliy
Цитата(EpLeon @ Mar 5 2016, 12:21) *
Честно говоря, прочитав данный текст, я только больше запутался... на align нужно подавать клок со сдвигом по фазе, в зависимости от того на сколько бит сдвинуть - на столько и задерживать фазу данного клока, или нет?

На align нужно подавать импульсы до наступления синхронизма,после этого ничего подавать не нужно. Примерно так - фаза не совпадает => дали один импульс align, проверили фазу,фаза не совпадает => дали один импульс align, проверили фазу и т.д.
EpLeon
Цитата(_Anatoliy @ Mar 5 2016, 15:26) *
На align нужно подавать импульсы до наступления синхронизма,после этого ничего подавать не нужно. Примерно так - фаза не совпадает => дали один импульс align, проверили фазу,фаза не совпадает => дали один импульс align, проверили фазу и т.д.

Имеется ввиду импульс любой длительности? Или туда что-то конкретное нужно подавать? Просто я сейчас туда подсоединил один из выходов PLL со сдвигом по фазе относительно основной частоты... То есть, я правильно понимаю, что сигнал поданный на align запускает подстройку фазы?
и еще вопрос - нужно ли такую подстройку проводить каждый раз при включении платы? Или же синхронизацию как-то можно запомнить?
_Anatoliy
Цитата(EpLeon @ Mar 5 2016, 12:58) *
Имеется ввиду импульс любой длительности? Или туда что-то конкретное нужно подавать? Просто я сейчас туда подсоединил один из выходов PLL со сдвигом по фазе относительно основной частоты... То есть, я правильно понимаю, что сигнал поданный на align запускает подстройку фазы?
и еще вопрос - нужно ли такую подстройку проводить каждый раз при включении платы? Или же синхронизацию как-то можно запомнить?

Вам же выше doom13 привёл требования к этому сигналу.
Цитата
The minimum pulse width is one period of the parallel clock in the logic array (rx_outclock).

Вот и подавайте импульс длительностью один такт указанной частоты. А для подстройки я использовал автомат т.к. во входном потоке у меня присутствовал байт-маркер,вставляемый через одинаковое количество байт.
EpLeon
Цитата(_Anatoliy @ Mar 5 2016, 16:25) *
Вам же выше doom13 привёл требования к этому сигналу.

Вот и подавайте импульс длительностью один такт указанной частоты. А для подстройки я использовал автомат т.к. во входном потоке у меня присутствовал байт-маркер,вставляемый через одинаковое количество байт.

Извините, но до меня немного долго доходит... Чтобы окончательно понять, я правильно понимаю, что в моем случае:
1) Каждый канал настраивается отдельно каждый раз при включении питания;
2) На ножку align[n-1..0] для каждого канала подается импульс длительностью в 1 такт клока. И подавать их нужно по принципу: подал импульс - посмотрел на данные -> совпали, значит настроилось, не совпали повторяем процедуру.
_Anatoliy
Цитата(EpLeon @ Mar 5 2016, 14:16) *

Насчёт каналов ничего не могу сказать,я с этим АЦП не работал.
Бегло глянул DS, так у вас же сигнал FCO есть,почему по нему не хотите синхронизироваться?
EpLeon
Цитата(_Anatoliy @ Mar 5 2016, 17:40) *
Насчёт каналов ничего не могу сказать,я с этим АЦП не работал.
Бегло глянул DS, так у вас же сигнал FCO есть,почему по нему не хотите синхронизироваться?

То есть по нему??? Имеете в виду подавать FCO на клок мегафункции (rx_inclock)?
doom13
Цитата(EpLeon @ Mar 5 2016, 14:16) *
Извините, но до меня немного долго доходит... Чтобы окончательно понять, я правильно понимаю, что в моем случае:
1) Каждый канал настраивается отдельно каждый раз при включении питания;
2) На ножку align[n-1..0] для каждого канала подается импульс длительностью в 1 такт клока. И подавать их нужно по принципу: подал импульс - посмотрел на данные -> совпали, значит настроилось, не совпали повторяем процедуру.

Всё так, только длительность импульса может быть и больше (выше приводил цитату из даташита, там указаны требования к сигналу align).

Цитата(EpLeon @ Mar 5 2016, 16:43) *
То есть по нему??? Имеете в виду подавать FCO на клок мегафункции (rx_inclock)?

Подача FCO на вход rx_inclock ядра не гарантирует правильного приёма фреймам (всё зависит от длины линий данных и клока), поэтому всё равно необходима синхронизация каналов.
_Anatoliy
Цитата(EpLeon @ Mar 5 2016, 16:43) *
То есть по нему??? Имеете в виду подавать FCO на клок мегафункции (rx_inclock)?

Ни в коем случае. Глянул ещё раз DS, рекомендую вам посмотреть в сторону регистра test_io, конкретно команда one-/zero-word toggle. Тогда после подачи питания включаете нужный режим test_io, калибруетесь подачей импульса align до тех пор пока не отловите пару слов 0х0000000000 и 0х1111111111, затем переходите в рабочий режим. Для формирования align напишите небольшой автомат, а FS можно не использовать.
EpLeon
Цитата(_Anatoliy @ Mar 6 2016, 13:22) *
Ни в коем случае. Глянул ещё раз DS, рекомендую вам посмотреть в сторону регистра test_io, конкретно команда one-/zero-word toggle. Тогда после подачи питания включаете нужный режим test_io, калибруетесь подачей импульса align до тех пор пока не отловите пару слов 0х0000000000 и 0х1111111111, затем переходите в рабочий режим. Для формирования align напишите небольшой автомат, а FS можно не использовать.

С этим тоже есть небольшая проблемка. Мне не очень понятно, как именно программировать АЦП. Как говорил раньше, с последовательными данными ни разу не работал. И в DS на оцифровщик мне не понятно, что такое W1/W2 и каким образом подавать последовательность слов. То есть как адрес соотносится с данными, которые я пытаюсь прописать. И если это нужно сделать в разные регистры.
Если вас не затруднит, не могли бы вы мне в этом помочь? И подсказать, как это сделать? Я понимаю, что прописав некоторое конкретное число в АЦП намного проще его потом отследить и можно сделать автомат на подстройку.
_Anatoliy
Цитата(EpLeon @ Mar 6 2016, 12:24) *

Так на figure 68 показан же формат обращения к АЦП. Слово 24 бита, три старшие из них - нули, биты 20...8 - адрес регистра, биты 7...0 - записываемые данные.
EpLeon
Цитата(_Anatoliy @ Mar 6 2016, 17:20) *
Так на figure 68 показан же формат обращения к АЦП. Слово 24 бита, три старшие из них - нули, биты 20...8 - адрес регистра, биты 7...0 - записываемые данные.

То есть я правильно понимаю, что если я хочу записать данные "1010" в регистр "0D" согласно таблице 9, то последовательность по этой линии будет: 000 000000001101 0001010 ?

И еще вопрос, а кто-нибудь пробовал сам делать защелкивание данных через DDR на такой частоте?
_Anatoliy
Цитата(EpLeon @ Mar 6 2016, 14:57) *
То есть я правильно понимаю, что если я хочу записать данные "1010" в регистр "0D" согласно таблице 9, то последовательность по этой линии будет: 000 000000001101 0001010 ?

И еще вопрос, а кто-нибудь пробовал сам делать защелкивание данных через DDR на такой частоте?

Примерно так, но должно быть 24 бита, а не 22. И обратите внимание на старшие 4 бита данных.
EpLeon
Цитата(_Anatoliy @ Mar 6 2016, 18:13) *
Примерно так, но должно быть 24 бита, а не 22. И обратите внимание на старшие 4 бита данных.

Да, заметил. Спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.