18.04.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 каналах:
[ Хронологический вид ]Комментарии
Войдите, чтобы комментировать.