18.04.2016 Вот теперь он синхронный

Материал из SRNS
Перейти к: навигация, поиск
(Новая страница: «<summary [ hidden ] > Кажется, это победа! </summary> {{TOCright}} 400px == Зачем? ==»)
 
Строка 1: Строка 1:
 
<summary [ hidden ] >
 
<summary [ hidden ] >
 +
 +
[[File:20160418_KDPV.gif|400px]]
  
 
Кажется, это победа!
 
Кажется, это победа!
Строка 6: Строка 8:
 
{{TOCright}}
 
{{TOCright}}
  
[[File:20160418_KDPV.gif|400px]]
+
== Предыстория ==
 +
 
 +
Была [[Blog:Boldenkov/05.04.2016_А_вы_думали,_коррелятор-синхронное_устройство%3F! | проблема с измерениями]]
 +
 
 +
== Симптомы ==
 +
 
 +
Если настроить все каналы на один и тот же сигнал и посмотреть разность измерений псевдодальности, получится что-то в этом роде:
 +
 
 +
[[File:20160415_CorrDiffRange_1.png|400px]]
 +
 
 +
В правой части - распределение разности измерений задержек по каналам коррелятора. Картинка повторяемая.
 +
 
 +
== В чём дело? ==
 +
 
 +
Для выяснения причин нужно углубиться в исходники коррелятора. Входные сигналы поступает в ПЛИС в последовательном виде по интерфесу LVDS. В ПЛИС стоит блок десериалайзера, преобразующий последовательный поток данных в параллельный. При этом десериалайзер также является источником тактового сигнала для остальной схемы:
 +
 
 +
<source lang="Verilog">
 +
zynq_deser_main #(
 +
  .D(`NUMBER_OF_LANE),
 +
  .REF_FREQ(200.0),
 +
  .CLKIN_PERIOD(8))
 +
  DESER (
 +
.refclk        (clk_200_buf), // Reference clock for input delay control
 +
.reset_delay  (!prog_reset),
 +
.CLK_LVDS_P    (clkin_p),
 +
`ifndef SINGLE_CLK_DESER
 +
.CLK_LVDS_N    (clkin_n), // lvds channel 1 clock input
 +
`endif
 +
.DAT_LVDS_P    (datain_p),
 +
.DAT_LVDS_N    (datain_n), // lvds channel 1 data inputs
 +
.gclk          (clk_adc_ext),
 +
.fpga_dat      (fpga_dat),
 +
.clk_dat      (),
 +
.dat_lock      (dat_lock),
 +
.debug        (debug)
 +
);
 +
</source>
 +
 
 +
Здесь данные - линии fpga_dat, а тактовый сигнал - clk_adc_ext.
 +
 
 +
Далее тактовый сигнал поступает на мультиплексор тактовых сигналов BUFGMUX:
 +
 
 +
<source lang="bash">
 +
  BUFGMUX #(
 +
    .CLK_SEL_TYPE("ASYNC")  // Glitchles ("SYNC") or fast ("ASYNC") clock switch-over
 +
  )
 +
  BUFGMUX_MUX0 (
 +
      .O(pclk),  // 1-bit output: Clock buffer output
 +
      .I0(aclk), // 1-bit input: Clock buffer input (S=0)
 +
      .I1(clk_adc_ext), // 1-bit input: Clock buffer input (S=1)
 +
      .S(clksource)    // 1-bit input: Clock buffer select
 +
  );
 +
</source>
 +
 
 +
Сигнал clksource выбирает, какой из тактовых сигналов будет поступать на pclk - либо clk_adc_ext, либо aclk. При этом BUFGMUX создаёт новый тактовый сигнал pclk.
 +
 
 +
Что происходит с данными десериалайзера? Они по-прежнему находятся в домене clk_adc_ext. И хотя тактовый сигнал pclk формируется из clk_adc_ext, с точки зрения Vivado они находятся в другом домене.
 +
 
 +
Что происходит дальше? Источник pclk - буфер BUFGMUX, находится в середине ПЛИС. Источник данных - десериалайзер - находится с краю ПЛИС. Эти сигналы (и pclk, и данные) распределяются между каналами коррелятора по всей ПЛИС.
 +
 
 +
Т.к. Vivado не рассматривает данные fpga_dat, как относящиеся к домену pclk, видимо, контроль задержек этих сигналов отсутствует. В результате этого сигналы, распространяясь по ПЛИС, приобретают разные задержки, которые мы и видим в измерениях.
 +
 
 +
На своём пути сигналы fpga_dat имеют кучу комбинационной логики - мультиплексоры сигналов в каждом из каналов и таблицы, осуществляющие перемножение на опорных сигнал. Первая синхронная операция - накопление в накопительном сумматоре. Неудивительно, что возникли проблемы.
 +
 
 +
== Попытки преодоления проблемы ==
 +
 
 +
Сначала был исключён мультиплексор тактовых сигналов. Казалось бы, это должно решить проблему, но нет.
 +
 
 +
Результаты для четырёх каналов:
 +
 
 +
[[File:20160418_CorrDiff_AssignPclk4_v1.png|400px]]
 +
 
 +
Разница в задержках исчезла!
 +
 
 +
Результаты для 80 каналов:
 +
 
 +
[[File:20160418_CorrDiff_AssignPclk80_v1.png|400px]]
 +
 
 +
Разница есть! Картинка отличается от той, что была раньше, но проблема осталась.
 +
 
 +
== Решение ==
 +
 
 +
Окончательным решением мне казалось не избавление от мультиплексора, а защёлкивание данных в тактах pclk.
 +
 
 +
<source lang="Verilog">
 +
  wire [7 * `NUMBER_OF_LANE - 1 : 0] fpga_dat;
 +
  reg  [7 * `NUMBER_OF_LANE - 1 : 0] fpga_dat_pclk;
 +
 
 +
  ...
 +
 
 +
  always @(posedge pclk) begin
 +
      fpga_dat_pclk <= fpga_dat;  // Transit from clk_adc_ext to pclk domain
 +
  end
 +
 
 +
  ...
 +
 
 +
  assign adc_sig0 = fpga_dat_pclk[0];
 +
  assign adc_mag0 = fpga_dat_pclk[7];
 +
  ...
 +
</source>
 +
 
 +
В результате этих изменений проблема была решена.
 +
 
 +
== Результаты ==
 +
 
 +
Работа 80 каналов коррелятора:
 +
 
 +
[[File:20160418_CorrDiff_RegData80_v1.png|400px]] [[File:20160418_CorrDiff_RegData80_v1a.png|400px]]
 +
 
 +
Собран коррелятор на 100 каналов. Если использовать только 80 из них, результат такой:
 +
 
 +
[[File:20160418_CorrDiff_RegData100_v1.png|400px]] [[File:20160418_CorrDiff_RegData100_v1a.png|400px]]
 +
 
 +
При использовании всех 100 каналов коррелятор работает, но производительности процессора на данный момент не хватает. Результаты при 100 каналах:
  
== Зачем? ==
+
[[File:20160418_CorrDiff_RegData100_v2.png|400px]]

Версия 12:25, 18 апреля 2016

Содержание

Предыстория

Была проблема с измерениями

Симптомы

Если настроить все каналы на один и тот же сигнал и посмотреть разность измерений псевдодальности, получится что-то в этом роде:

20160415 CorrDiffRange 1.png

В правой части - распределение разности измерений задержек по каналам коррелятора. Картинка повторяемая.

В чём дело?

Для выяснения причин нужно углубиться в исходники коррелятора. Входные сигналы поступает в ПЛИС в последовательном виде по интерфесу LVDS. В ПЛИС стоит блок десериалайзера, преобразующий последовательный поток данных в параллельный. При этом десериалайзер также является источником тактового сигнала для остальной схемы:

        zynq_deser_main #(
                .D(`NUMBER_OF_LANE),
                .REF_FREQ(200.0),
                .CLKIN_PERIOD(8))
        DESER (
                .refclk        (clk_200_buf),                   // Reference clock for input delay control
                .reset_delay   (!prog_reset),
                .CLK_LVDS_P    (clkin_p),
                `ifndef SINGLE_CLK_DESER
                .CLK_LVDS_N    (clkin_n),                       // lvds channel 1 clock input
                `endif
                .DAT_LVDS_P    (datain_p),
                .DAT_LVDS_N    (datain_n),                      // lvds channel 1 data inputs
                .gclk          (clk_adc_ext),
                .fpga_dat      (fpga_dat),
                .clk_dat       (),
                .dat_lock      (dat_lock),
                .debug         (debug)
        );

Здесь данные - линии fpga_dat, а тактовый сигнал - clk_adc_ext.

Далее тактовый сигнал поступает на мультиплексор тактовых сигналов BUFGMUX:

        BUFGMUX #(
        .CLK_SEL_TYPE("ASYNC")  // Glitchles ("SYNC") or fast ("ASYNC") clock switch-over
        )
        BUFGMUX_MUX0 (
        .O(pclk),   // 1-bit output: Clock buffer output
        .I0(aclk), // 1-bit input: Clock buffer input (S=0)
        .I1(clk_adc_ext), // 1-bit input: Clock buffer input (S=1)
        .S(clksource)    // 1-bit input: Clock buffer select
        );

Сигнал clksource выбирает, какой из тактовых сигналов будет поступать на pclk - либо clk_adc_ext, либо aclk. При этом BUFGMUX создаёт новый тактовый сигнал pclk.

Что происходит с данными десериалайзера? Они по-прежнему находятся в домене clk_adc_ext. И хотя тактовый сигнал pclk формируется из clk_adc_ext, с точки зрения Vivado они находятся в другом домене.

Что происходит дальше? Источник pclk - буфер BUFGMUX, находится в середине ПЛИС. Источник данных - десериалайзер - находится с краю ПЛИС. Эти сигналы (и pclk, и данные) распределяются между каналами коррелятора по всей ПЛИС.

Т.к. Vivado не рассматривает данные fpga_dat, как относящиеся к домену pclk, видимо, контроль задержек этих сигналов отсутствует. В результате этого сигналы, распространяясь по ПЛИС, приобретают разные задержки, которые мы и видим в измерениях.

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

Попытки преодоления проблемы

Сначала был исключён мультиплексор тактовых сигналов. Казалось бы, это должно решить проблему, но нет.

Результаты для четырёх каналов:

20160418 CorrDiff AssignPclk4 v1.png

Разница в задержках исчезла!

Результаты для 80 каналов:

20160418 CorrDiff AssignPclk80 v1.png

Разница есть! Картинка отличается от той, что была раньше, но проблема осталась.

Решение

Окончательным решением мне казалось не избавление от мультиплексора, а защёлкивание данных в тактах pclk.

   wire [7 * `NUMBER_OF_LANE - 1 : 0] fpga_dat;
   reg  [7 * `NUMBER_OF_LANE - 1 : 0] fpga_dat_pclk;

   ...

   always @(posedge pclk) begin
      fpga_dat_pclk <= fpga_dat;  // Transit from clk_adc_ext to pclk domain
   end

   ...

   assign adc_sig0 = fpga_dat_pclk[0];
   assign adc_mag0 = fpga_dat_pclk[7];
   ...

В результате этих изменений проблема была решена.

Результаты

Работа 80 каналов коррелятора:

20160418 CorrDiff RegData80 v1.png 20160418 CorrDiff RegData80 v1a.png

Собран коррелятор на 100 каналов. Если использовать только 80 из них, результат такой:

20160418 CorrDiff RegData100 v1.png 20160418 CorrDiff RegData100 v1a.png

При использовании всех 100 каналов коррелятор работает, но производительности процессора на данный момент не хватает. Результаты при 100 каналах:

20160418 CorrDiff RegData100 v2.png

[ Хронологический вид ]Комментарии

(нет элементов)

Войдите, чтобы комментировать.

Персональные инструменты
Пространства имён

Варианты
Действия
SRNS Wiki
Рабочие журналы
Приватный файлсервер
QNAP Сервер
Инструменты