|
|
  |
Подключение скоростного АЦП к Spartan-6 |
|
|
|
Jul 26 2012, 02:43
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 30-11-11
Пользователь №: 68 594

|
А почему 200 МГц? Если 100 МГц по 16 бит будет 1600 Мбит/с то выходной поток будет по каждой диф паре 800 Мбит/с xapp1064.pdf Вам в помощь
|
|
|
|
|
Jul 26 2012, 05:20
|
Знающий
   
Группа: Свой
Сообщений: 802
Регистрация: 11-05-07
Из: Томск
Пользователь №: 27 650

|
Цитата(maxics @ Jul 25 2012, 22:19)  Имеется АЦП LTC2195 (2 канала Serial LVDS). Оцифровка 100 МГц. Дифф. пары с АЦП подключены к Spartan-6 LX75. Оцифрованные данные передаются по переднему и заднему фронтам 200 МГц. Как все это дело лучше принимать в ПЛИС? Вы тут путаете чегой-то... Если вы хотите пользовать 2-lane output mode, то тактовая частота на каждой из дифф. пар будет 400 МГц, это даст 800мБит с каждой паре и 1600мБит в сумме, как раз 16бит на 100МГц. На Спартане 6 - вполне подъёмно, но лучше бы вам попользовать 4 lane mode - дополнительно 2 пары, зато требования к частотке в два раза ниже. Пользуйте ISERDES + BUFIO2. Если вдруг возникнут проблемы с таймингами (не забывайте про constraints) можно попользовать DCM и подвигать фазу клоков относительно данных. Но скорее всего это не понадобится. Всё вполне подъёмно и проходимо. Но придётся малость почитать доки и погрузиться во внутреннюю архитектуру Спартана6. З Ы На этапе проектирования платы не забудьте развести клоки на клоковые входы Спартана, и данные - на соответствующие дифф.пары. Иначе - не будет вам счастья...
|
|
|
|
|
Jul 26 2012, 06:06
|
Местный
  
Группа: Участник
Сообщений: 229
Регистрация: 16-11-09
Пользователь №: 53 649

|
Цитата(Bad0512 @ Jul 26 2012, 09:20)  Вы тут путаете чегой-то... Если вы хотите пользовать 2-lane output mode, то тактовая частота на каждой из дифф. пар будет 400 МГц, это даст 800мБит с каждой паре и 1600мБит в сумме, как раз 16бит на 100МГц. На Спартане 6 - вполне подъёмно, но лучше бы вам попользовать 4 lane mode - дополнительно 2 пары, зато требования к частотке в два раза ниже. Пользуйте ISERDES + BUFIO2. Если вдруг возникнут проблемы с таймингами (не забывайте про constraints) можно попользовать DCM и подвигать фазу клоков относительно данных. Но скорее всего это не понадобится. Всё вполне подъёмно и проходимо. Но придётся малость почитать доки и погрузиться во внутреннюю архитектуру Спартана6.
З Ы На этапе проектирования платы не забудьте развести клоки на клоковые входы Спартана, и данные - на соответствующие дифф.пары. Иначе - не будет вам счастья... Буду использовать 4 lane mode.
В этом режиме получается, если оцифровка 100 МГц, то вых. отчеты будут защелкиваться в ПЛИС по обоим фронтам DCO, который и будет 200 Мгц. Правильно я понимаю ситуацию?
|
|
|
|
|
Jul 26 2012, 06:37
|
Знающий
   
Группа: Свой
Сообщений: 802
Регистрация: 11-05-07
Из: Томск
Пользователь №: 27 650

|
Цитата(maxics @ Jul 26 2012, 13:06)  Буду использовать 4 lane mode.
В этом режиме получается, если оцифровка 100 МГц, то вых. отчеты будут защелкиваться в ПЛИС по обоим фронтам DCO, который и будет 200 Мгц. Правильно я понимаю ситуацию? да, правильно.
|
|
|
|
|
Jul 26 2012, 08:20
|
Знающий
   
Группа: Свой
Сообщений: 716
Регистрация: 27-05-05
Из: Kyiv
Пользователь №: 5 454

|
Я прорабатывал проект съема данных с CCD линейки CCD143A("Refract 14 jan 2011.rar"). Предполагалось использовать похожий АЦП(ADS6242) и Spartan3E. В архиве две платы(эскизы PCAD2006) одна для линейки, вторая АЦП и ПЛИС. В третьей папке проект для ПЛИС(ISE 10.2). Объем данных с линейки небольшой. Предполагалось что ПЛИС управляется по SPI. Командами по SPI должно было производится чтение линейки в буфер Внутри ПЛИС и получение данных их буфера по SPI. В проекте есть описание ПЛИС, модель АЦП и тестбенч для проверки. Для использования LVDS I/O нужно в проекте использовать примитивы(adc_data_interface.v). Для выходов, входов буферов и т.д. Код // Трансляция тактирования от кварца на АЦП OBUFDS #(.IOSTANDARD("LVDS_25")) lvds_clk_obuf ( .I(crystal_clk), .O(adc_clkp), .OB(adc_clkm) );
...
// Входной буфер побитового тактирования с АЦП IBUFGDS #(.IOSTANDARD("LVDS_25"), .IBUF_DELAY_VALUE("0"), .DIFF_TERM("TRUE")) lvds_bit_clk_ibuf (.I(adc_bit_clkp), .IB(adc_bit_clkm), .O(bit_clk) );
...
// Входные буфера данных с АЦП IBUFDS #(.IOSTANDARD("LVDS_25"), .IFD_DELAY_VALUE("0"), .DIFF_TERM("TRUE")) lvds_bit_a0_ibuf (.I(adc_da0_p), .IB(adc_da0_m), .O(inv_bit_A0) );
...
// Входные DDR регистры данных IDDR2 #(.DDR_ALIGNMENT("C0")) fd_io_0 (.C0(rxclk_dcm), .C1(rxclk_dcm_180), .D(inv_bit_A0), .CE(1'b1), .R(1'b0), .S(1'b0), .Q0(data_in_reg_A0[0]), .Q1(data_in_reg_A0[1])); Банк где используются LVDS нужно запитать от 2,5V. В противном случае .DIFF_TERM("TRUE") вызовет ошибку. При синтезе проекта нужно обязательно назначить выводы в ucf файле. И "перетасовать" их под PCB. Как ни странно, некоторые дифференциальные входы не имеют внутреннего терминирующего резистора.
|
|
|
|
|
Jul 26 2012, 13:18
|
Знающий
   
Группа: Свой
Сообщений: 740
Регистрация: 24-07-06
Из: Minsk
Пользователь №: 19 059

|
QUOTE (misyachniy @ Jul 26 2012, 06:20)  Как ни странно, некоторые дифференциальные входы не имеют внутреннего терминирующего резистора. это только пины двойного назначения. вы еще с алтерой не работали , там половина портов не имеет терминаторов.
|
|
|
|
|
Jan 25 2013, 02:04
|

Гуру
     
Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988

|
Цитата(maxics @ Jan 25 2013, 01:35)  Сделал плату, все работает. Встал вопрос приема данных с этой АЦП. Пробовал тупо защелкивать по переднему и заднему фронту. Ничего хорошего не получилось. Посоветуйте как правильно принимать Serial LVDS по обоим фронтам. нужны ddr-регистры (это пара регистров, тактируемых в противофазе). на выходе число бит будет удвоено относительно входа. я не знаю, как называется примитив ddr_input у xilinx, на альтере я делал так: CODE module adc_deserializer #(parameter ch_num = 8, ser_factor = 14, invert_input_clock = "OFF") ( input bit_clk, input frame_clk, input reset_n, input [ch_num-1:0] adc_data_serial, output reg [ser_factor-1:0] adc_data[ch_num] ); reg [1:0] frame_clk_reg = '0; integer n; always_ff @(posedge bit_clk) begin frame_clk_reg <= {frame_clk_reg, frame_clk}; end wire frame_clk_rising_edge = frame_clk_reg[0]&(!frame_clk_reg[1]); genvar i; generate for(i = 0; i < ch_num; i++) begin: lvds_rx reg [ser_factor-1:0] lvds_sr = '0; wire dataout_h; wire dataout_l; altddio_in altddio_in_inst ( .aclr(1'b0), .datain(adc_data_serial[i]), .inclock(bit_clk), .dataout_h(dataout_h), .dataout_l(dataout_l), .aset(1'b0), .inclocken(1'b1) ); defparam altddio_in_inst.intended_device_family = "Cyclone IV GX", altddio_in_inst.invert_input_clocks = invert_input_clock, altddio_in_inst.lpm_hint = "UNUSED", altddio_in_inst.lpm_type = "altddio_in", altddio_in_inst.power_up_high = "ON"/*"OFF"*/, altddio_in_inst.width = 1; always_ff @(posedge bit_clk) begin lvds_sr <= {lvds_sr[ser_factor-3:0], dataout_l, dataout_h}; end always_ff @(posedge bit_clk) begin if (!reset_n) adc_data[i] <= '0; else if (frame_clk_rising_edge) adc_data[i] <= lvds_sr; end end endgenerate endmodule
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|