18.04.2016 Вот теперь он синхронный
Boldenkov (обсуждение | вклад) (Новая страница: «<summary [ hidden ] > Кажется, это победа! </summary> {{TOCright}} 400px == Зачем? ==») |
Boldenkov (обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
<summary [ hidden ] > | <summary [ hidden ] > | ||
+ | |||
+ | [[File:20160418_KDPV.gif|400px]] | ||
Кажется, это победа! | Кажется, это победа! | ||
Строка 6: | Строка 8: | ||
{{TOCright}} | {{TOCright}} | ||
− | [[File: | + | == Предыстория == |
+ | |||
+ | Была [[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
|
Предыстория
Симптомы
Если настроить все каналы на один и тот же сигнал и посмотреть разность измерений псевдодальности, получится что-то в этом роде:
В правой части - распределение разности измерений задержек по каналам коррелятора. Картинка повторяемая.
В чём дело?
Для выяснения причин нужно углубиться в исходники коррелятора. Входные сигналы поступает в ПЛИС в последовательном виде по интерфесу LVDS. В ПЛИС стоит блок десериалайзера, преобразующий последовательный поток данных в параллельный. При этом десериалайзер также является источником тактового сигнала для остальной схемы:
.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:
.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 имеют кучу комбинационной логики - мультиплексоры сигналов в каждом из каналов и таблицы, осуществляющие перемножение на опорных сигнал. Первая синхронная операция - накопление в накопительном сумматоре. Неудивительно, что возникли проблемы.
Попытки преодоления проблемы
Сначала был исключён мультиплексор тактовых сигналов. Казалось бы, это должно решить проблему, но нет.
Результаты для четырёх каналов:
Разница в задержках исчезла!
Результаты для 80 каналов:
Разница есть! Картинка отличается от той, что была раньше, но проблема осталась.
Решение
Окончательным решением мне казалось не избавление от мультиплексора, а защёлкивание данных в тактах pclk.
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 каналов коррелятора:
Собран коррелятор на 100 каналов. Если использовать только 80 из них, результат такой:
При использовании всех 100 каналов коррелятор работает, но производительности процессора на данный момент не хватает. Результаты при 100 каналах:
[ Хронологический вид ]Комментарии
Войдите, чтобы комментировать.