реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Корректный сброс при изменении задающей частоты
Fourier
сообщение Mar 7 2016, 21:22
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 13-02-13
Из: Рыбинск
Пользователь №: 75 606



Здравствуйте!

Имеется плата с АЦП, ЦАПом и Spartan-6 на борту. Тактирование АЦП и ЦАП осуществляется синтезатором через дестрибьютер тактовых сигналов, частота дискретизации 125 МГц.
Дифф. тактовый сигнал от АЦП заводится в глобальную шину синхронизации и используется для синхронизации модулей ЦОС. Сигнал сброса на эти модули естесственно выдается с задержкой после включения.

Проводили испытания на климат и на морозе плата стала сбоить. Я сделал тестовую прошивку с возможность сброса части логики и оказалось, что сбоит логика тактируемая этим сигналом при прогреве платы во время работы.

Начал экспериментировать - замыкать входы синхронизации и действительно при кратковременном пропадании тактового сигнала логика перестает работать навечно.

Предполагаю, что при прогреве платы происходит кратковременное изменение фазы или частоты схемы тактирования. Однако, повторный сброс части логики ПЛИС решает все проблемы.

Подал клок АЦП на DCM и стал мониторить его сигналы LOCKED, STATUS, CLK_VALID, CLK_STOPPED. Сделал конечный автомат, отслеживающий их и формирующий сброс.
И снова стал замыкать дифф. пару. В 90 процентах случаев конечный автомат вырабатывает корректный сигнал сброса и работа логики восстанавливается.
Однако, иногда при кратковременном пропадании клока все сигналы DCM говорят о том, что все хорошо, а логика моя не работает, поскольку я ее не сбросил. (((( Ну об этом и UG382 говорит, как я понял, типа не рассчитывайте особа на сигналы состояний DCM. Вырабатывать сброс периодически не хочется.

Вопрос в следующем: как можно железно отследить кратковременные сбои тактирующего сигнал и сформировать сигнал сброса для логики тактируемой им?
Конечно, можно и с задающей схемой еще поковыряться, но мне не нравится такой расклад: клок пропал - все перестало работать на вечно, даже после его восстановления(((((

Заранее спасибо


Go to the top of the page
 
+Quote Post
VladimirB
сообщение Mar 7 2016, 21:51
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 614
Регистрация: 12-06-09
Из: рядом с Москвой
Пользователь №: 50 219



Цитата(Fourier @ Mar 8 2016, 00:22) *
Здравствуйте!

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

Заранее спасибо


1) Взятьу LockDetect с синтезатора и если он пропадает, то сброс
2) А ещё у синтезаторов/дистрибутеров от АналоговыхДевиц обычно есть галочка MuteTillLockDetect ("заткнись пока не залочился" (С) ) - её ставлю, тогда и сброса не надо.
Go to the top of the page
 
+Quote Post
TRILLER
сообщение Mar 8 2016, 12:28
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 180
Регистрация: 17-02-09
Из: Санкт-Петербург
Пользователь №: 45 001



Цитата(Fourier @ Mar 8 2016, 00:22) *
Однако, иногда при кратковременном пропадании клока все сигналы DCM говорят о том, что все хорошо, а логика моя не работает, поскольку я ее не сбросил. (((( Ну об этом и UG382 говорит, как я понял, типа не рассчитывайте особа на сигналы состояний DCM.

Сигналы DCM говорят что всё хорошо, потому как всё действительно хорошо. Лично наблюдал не один раз, что опору DCM можно вообще убрать, а DCM и вся логика запущенная от этого DCMа будет работать как ни в чём не бывало. rolleyes.gif
Я бы вам посоветовал не пытаться детектировать ошибку входного синхроимпульса, а запустить работу логики от DCM. Непосредственно входным же тактом осуществлять только захват данных в ножках. Таким образом неполадки опорной тактовой будут приводить всего лишь к потере нескольких тактов данных, а не к умиранию всей схемы.
Go to the top of the page
 
+Quote Post
Fourier
сообщение Mar 8 2016, 12:52
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 13-02-13
Из: Рыбинск
Пользователь №: 75 606



Цитата(TRILLER @ Mar 8 2016, 15:28) *
Я бы вам посоветовал не пытаться детектировать ошибку входного синхроимпульса, а запустить работу логики от DCM. Непосредственно входным же тактом осуществлять только захват данных в ножках. Таким образом неполадки опорной тактовой будут приводить всего лишь к потере нескольких тактов данных, а не к умиранию всей схемы.


Спасибо за совет.

Я так и сделал сейчас, правда еще есть схема мониторинга состояния DCM и сброса при отсутствии захвата. Но в первом приближении косяк остался, завтра буду продолжать разбираться, может что-то не корректно сделал.

Еще вопрос до кучи)))

Чем отличается STATUS[1] от INPUT_CLK_STOPPED Clocking Wizarda. Не могу нигде найти. По тестбенчам они совпадают вроде.

P.S. А ничем и не отлчаются они
assign INPUT_CLK_STOPPED = status_int[1];

Цитата(TRILLER @ Mar 8 2016, 15:28) *
Я бы вам посоветовал не пытаться детектировать ошибку входного синхроимпульса, а запустить работу логики от DCM. Непосредственно входным же тактом осуществлять только захват данных в ножках. Таким образом неполадки опорной тактовой будут приводить всего лишь к потере нескольких тактов данных, а не к умиранию всей схемы.


Подскажите, пожалуйста, а можно ли и захват данных сделать от DCM, так как у меня BUFG дефицит. Если делать так как Вы говорите, по моему, нужно 2 BUFG на ввод дифф. тактовой пары, от них на IDDR2 синхронизацию подать и их же завести на вход DCM, плюс один BUFG - выход DCM.

Или я что-то не так делаю))) Буду очень рад советам.

Вот старый вариант кода сбора данных (без DCM, который отказывает на морозе). От out_dclk тактируется остальная логика.
Покритикуйте, пожалуйста. Может где подводные камни есть.

Код
module ad9613_rx #
(
   parameter   DIFF_TERM = "FALSE" // Parameter to enable internal differential termination
)
(
   // Данные
    input [ADC_WIDTH - 1 : 0] in_data_p,
    input [ADC_WIDTH - 1 : 0] in_data_n,
   // Синхронизация
    input in_dco_p,
    input in_dco_n,
    input in_adc_or_p,
    input in_adc_or_n,
    
    // Выходы
    output out_dclk,
    output reg [ADC_WIDTH - 1 : 0] out_data_0,
    output reg [ADC_WIDTH - 1 : 0] out_data_1
);

localparam ADC_WIDTH = 12;

wire w_dco_p;
wire w_dco_n;

wire w_dco_bufg_p;
wire w_dco_bufg_n;

wire [ADC_WIDTH - 1 : 0] w_rx_data_in;
wire [ADC_WIDTH - 1 : 0] w_rx_data_in_fix;

wire [ADC_WIDTH - 1 : 0] w_rx_data_0;
wire [ADC_WIDTH - 1 : 0] w_rx_data_1;

// Выходной клок
assign out_dclk = w_dco_bufg_p;

parameter     [ADC_WIDTH - 1 : 0] RX_SWAP_MASK = 12'h0000;    // pinswap mask for input bits (0 = no swap (default), 1 = swap). Allows inputs to be connected the wrong way round to ease PCB routing.

genvar     i;

// Входной буфер для клока (формирует дифференциальные сигналы
IBUFGDS_DIFF_OUT IBUFGDS_DIFF_OUT_ADC_DCO (
   .O(w_dco_p),   // Buffer diff_p output
   .OB(w_dco_n),  // Buffer diff_n output
   .I(in_dco_p),  // Diff_p buffer input (connect directly to top-level port)
   .IB(in_dco_n)  // Diff_n buffer input (connect directly to top-level port)
);

// Заводим в глобальную шину синхронизации
BUFG BUFG_ADC_DCO_P (
   .O(w_dco_bufg_p),   // 1-bit output: Clock buffer output
   .I(w_dco_p)    // 1-bit input: Clock buffer input
);

BUFG BUFG_ADC_DCO_N (
   .O(w_dco_bufg_n),   // 1-bit output: Clock buffer output
   .I(w_dco_n)    // 1-bit input: Clock buffer input
);

// Генерация входных буферов
generate
for (i = 0; i < ADC_WIDTH; i = i + 1)
begin : loop0

  
   // Входной дифф. буфер
   IBUFDS #(
      .DIFF_TERM         (DIFF_TERM))
   data_in (
      .I                (in_data_p[i]),
      .IB               (in_data_n[i]),
      .O                 (w_rx_data_in[i])
      );
      
   // При необходимости проводим инверсию данных  
   assign w_rx_data_in_fix[i] = w_rx_data_in[i] ^ RX_SWAP_MASK[i]; // Invert data signals as required
  
   // DDR
   IDDR2 #(
      .DDR_ALIGNMENT("C0")          // Sets output alignment to "NONE", "C0" or "C1"      
   ) IDDR2_D0D1 (
      .Q0 ( w_rx_data_0[i] ),       // 1-bit output captured with C0 clock
      .Q1 ( w_rx_data_1[i] ),       // 1-bit output captured with C1 clock
      .C0 ( w_dco_p),               // 1-bit clock input
      .C1 ( w_dco_n),               // 1-bit clock input
      .CE (1'b1),                   // 1-bit clock enable input
      .D  (w_rx_data_in_fix[i]),    // 1-bit DDR data input
      .R  (1'b0),                   // 1-bit reset input
      .S  (1'b0)                    // 1-bit set input
   );
  
end
endgenerate

// Защелкиваем выходные данные
always @(posedge out_dclk)
begin
   out_data_0 <= w_rx_data_0;
   out_data_1 <= w_rx_data_1;
end

endmodule


Сообщение отредактировал Fourier - Mar 8 2016, 12:58
Go to the top of the page
 
+Quote Post
Lmx2315
сообщение Mar 8 2016, 12:56
Сообщение #5


отэц
*****

Группа: Свой
Сообщений: 1 729
Регистрация: 18-09-05
Из: Москва
Пользователь №: 8 684



..странно что при кратковременном пропадании клоков у вас схема виснет, я так понял там просто жёсткое DSP какое-то, оно может виснуть только если клоков нет совсем.


--------------------
b4edbc0f854dda469460aa1aa a5ba2bd36cbe9d4bc8f92179f 8f3fec5d9da7f0
SHA-256
Go to the top of the page
 
+Quote Post
Fourier
сообщение Mar 8 2016, 13:06
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 13-02-13
Из: Рыбинск
Пользователь №: 75 606



Цитата(Lmx2315 @ Mar 8 2016, 15:56) *
..странно что при кратковременном пропадании клоков у вас схема виснет, я так понял там просто жёсткое DSP какое-то, оно может виснуть только если клоков нет совсем.


Угу, мне тоже странно.

Виснет кусок схемы, который вычисляет корреляцию с кодом Баркера.

Код
module bin_correlator #
(
   parameter SPS        = 40,
   parameter CODE       = 11'b11100010010,
   parameter CODE_WIDTH = 11,
   parameter TRESHOLD   = SPS*CODE_WIDTH - 2*CODE_WIDTH
)
(
    input in_clk,
    input in_data,
    input in_reset,
    input in_enable,
    output reg out_threshold,
    output reg out_peak,
    output reg [CODE_WIDTH - 1 : 0] out_data
);

// Ширина регистра с задержанными данными
localparam D_WIDTH   = SPS*(CODE_WIDTH + 1);
localparam SUM_WIDTH = 8;
localparam MUL_WIDTH = 10;

// Буфер для сохранения задержанных двоичных данных
reg [D_WIDTH - 1 : 0] delayed_buf;

// Буфер с суммами на отсчет
reg signed [SUM_WIDTH - 1 : 0] sum_buf [CODE_WIDTH-1 : 0];

// Буфер с корреляционными произведениями
reg signed [SUM_WIDTH - 1 : 0] corr_mul_buf [CODE_WIDTH-1 : 0];

// Буфер, хранящий значения вычисленных ВКФ
reg signed [MUL_WIDTH - 1 : 0] sum_mul;

// Буфер с добавками к сумме
reg signed [2 : 0] add_buf [CODE_WIDTH-1 : 0];

// Буфер с кодом свертки
reg [CODE_WIDTH-1 : 0] code = CODE;

reg _is_old_threshold;
reg signed [MUL_WIDTH - 1 : 0] _old_corr_func;  //
reg signed [MUL_WIDTH - 1 : 0] _corr_func;      //
wire _is_threshold = (_corr_func >= TRESHOLD);

integer i;

initial
begin
   reset_task();
end

    
always @(posedge in_clk)
begin
   if(in_reset)
   begin
      reset_task();
   end
   else
   begin
      process_task();
   end
end

// Процесс обработки данных
task process_task;
   begin
      // Сдвиг данных в регистр
     delayed_buf <= {delayed_buf[D_WIDTH - 2 : 0], in_data};
      
     sum_mul = 0;
    
     // Вычисление сумм на символ
     for(i = 0; i < CODE_WIDTH; i = i + 1)
     begin
        
         // Вычисление добавки к символу
         add_buf[i] <= $signed({delayed_buf[i*SPS], 1'b1}) - $signed({delayed_buf[(i + 1)*SPS], 1'b1});
        
         // Вычисление суммы на символ
         sum_buf[i] <= sum_buf[i] + add_buf[i];
        
         // Вычисление значений символа
         out_data[i] <= $signed(sum_buf[i]) < $signed(0);
        
         // Вычисление корреляционных произведений
         corr_mul_buf[i] <= code[i] ? -sum_buf[i] : sum_buf[i];
        
         // Выисление суммы корреляционных произведений
         sum_mul    = sum_mul + corr_mul_buf[i];
     end
      
      //
      _corr_func     <= sum_mul;
      
      //
      out_threshold <= (sum_mul >= TRESHOLD);
      
      // Save old Function State
      _old_corr_func     <= _corr_func;
      
      // Save old threshold state
      _is_old_threshold <= _is_threshold;
      
      // Correlation Peak
     out_peak   <= (_is_old_threshold) & (_corr_func < _old_corr_func);

end
endtask

// Процесс сброса
task reset_task;
   begin
      code <= CODE;
      for(i = 0; i < SPS*CODE_WIDTH + 1; i = i + 1)
      begin
         delayed_buf[i] <= 1'b0;
      end;
      for(i = 0; i < CODE_WIDTH; i = i + 1)
      begin
         sum_buf[i] <= SPS - 1;
         add_buf[i] <= 0;
         out_data   <= 0;
      end
   end
endtask



endmodule


Сообщение отредактировал Fourier - Mar 8 2016, 13:14
Go to the top of the page
 
+Quote Post
TRILLER
сообщение Mar 8 2016, 14:57
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 180
Регистрация: 17-02-09
Из: Санкт-Петербург
Пользователь №: 45 001



Цитата(Fourier @ Mar 8 2016, 15:52) *
Подскажите, пожалуйста, а можно ли и захват данных сделать от DCM, так как у меня BUFG дефицит. Если делать так как Вы говорите, по моему, нужно 2 BUFG на ввод дифф. тактовой пары, от них на IDDR2 синхронизацию подать и их же завести на вход DCM, плюс один BUFG - выход DCM.

Как правильно сделать вам расскажет документ Прикрепленный файл  Spartan_6_FPGA_Clocing_Resources_ug382_.pdf ( 3.16 мегабайт ) Кол-во скачиваний: 297
на страницах 33-34. Выбираете вашу схему и реализуете.
Go to the top of the page
 
+Quote Post
Timmy
сообщение Mar 9 2016, 07:08
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



Можете показать файл с констрейнами? А то меня терзают смутные сомнения, что констрейны даже на частоту не заданы, не говоря уж про ввод-вывод.
Go to the top of the page
 
+Quote Post
bogaev_roman
сообщение Mar 9 2016, 08:59
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 088
Регистрация: 20-10-09
Из: Химки
Пользователь №: 53 082



Цитата(Timmy @ Mar 9 2016, 10:08) *
Можете показать файл с констрейнами? А то меня терзают смутные сомнения, что констрейны даже на частоту не заданы, не говоря уж про ввод-вывод.

Поддерживаю вопрос, с этого и следовало начать. Сам использую стандартный метод формирования асинхронного сброса по сигналу LOCKED модуля clocking wizard (откуда, кстати, DCM?) за пару лет на нескольких разных платах в этом месте глюков замечено не было.
Go to the top of the page
 
+Quote Post
Fourier
сообщение Mar 9 2016, 17:27
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 13-02-13
Из: Рыбинск
Пользователь №: 75 606



Цитата(bogaev_roman @ Mar 9 2016, 11:59) *
Поддерживаю вопрос, с этого и следовало начать. Сам использую стандартный метод формирования асинхронного сброса по сигналу LOCKED модуля clocking wizard (откуда, кстати, DCM?) за пару лет на нескольких разных платах в этом месте глюков замечено не было.


Вот констрейны на частоту
Код
# ADC DCO
NET "ADC_DCO_P" TNM_NET = "ADC_DCO";
NET "ADC_DCO_N" TNM_NET = "ADC_DCO";
TIMESPEC TS_ADC_DCO = PERIOD "ADC_DCO" 120 MHz HIGH 50 %;


Вот на данные

Код
#PIN "ADC_D_*" TNM =  "GRP_ADC_DATA";
#TIMEGRP "GRP_ADC_DATA" OFFSET = IN 3 ns BEFORE "ADC_DCO" RISING;
#TIMEGRP "GRP_ADC_DATA" OFFSET = IN 3 ns BEFORE "ADC_DCO" FALLING;


Ошибок временных нет.

P.S. прошу прощения констрейны данных закомментированы оказались. Но вся логика без временных ошибок, включая тот дикий сумматор на 11 элементов, который надо бы переделать.

Все похоже оказалось несколько проще))) На борту стоит дистрибьютер AD9515. OUT0 - LVPECL тактирует ЦАП, а OUT1 сконфигурированный как LVDS - АЦП.
Так вот оказалось, что peak-to-peak OUT1 по одной линии диффпары порядка 2.5 В, а по второй - 1.4. Причем эти уровни изменяются при нагреве. Т.е. это совсем не дифф.пара и совсем не LVDS((((
Так пока и не разобрался в чем причина, вроде схема по даташитам сделана. На второй плате работает все норм во всем диапазоне температур.
Замена микросхемы эффекта не дала, хотя есть подозрение что монтажница повторно установила неисправную.

Вот собственно говоря схемы.

Дистрибьютер



АЦП





Сообщение отредактировал Fourier - Mar 9 2016, 17:46
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 14:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.01453 секунд с 7
ELECTRONIX ©2004-2016