Перейти к содержанию

    

Констрейны для клока, мультиплексированного в FPGA и умноженного снаружи

Добрый день

Много думал и стал сомневаться 

Spoiler

Gkny6bjBrYs.jpg.b50237e51a14c809cff2a7db6b0d9fb3.jpg

на рисунке нарисовал одно внешнее устройство для упрощения, второе подключено точно так же

Суть в следующем. Имеется отладочная плата с FPGA, к ней подключены два внешних устройства. На вход устройств необходимо подавать 24МГц, внутри каждого устройства эта частота умножается (коэффициент можно задать) и устройства начинают отправлять в FPGA данные. Данные передаются пачками по 8-битной шине и сопровождаются стробом. В FPGA пачки данных необходимо обрабатывать одновременно. Для этого заведены 2 FIFO, запись в них производится на частотах внешних устройств, вычитываем одновременно на системной частоте когда приняты обе пачки. Видимо из-за разницы в умножении частот, стробы постепенно начинают расползаться во времени и в итоге одно из FIFO переполняется, вся система рушится. Для борьбы с этим, на системной частоте отслеживаем начала стробов и когда они расползлись слишком сильно, переключаем частоту с 24МГц на 23.5 МГц для убегающего устройства, когда стробы выровнялись возвращаем обратно 24 МГц. Переключения производятся в момент, когда данных нет.

Этот концепт работает, но при задании констрейнов я стал сомневаться. Суть сомнений в следующем.

Сначала я просто задал виртуальный клок, для каждого из внешних устройств, задал клоки на входных пинах и прописал set_input_delay для сигналов в шине и для строба. То есть сделал как будто нет никакой связи внешнего клока и любых клоков в ПЛИС. Но это не совсем честно, связь то все-таки есть и отсюда началась путаница. Я попробовал задать клок для внешнего устройства как create_generated_clock. Умножив на 2 клок выхода с мультиплексора клоков. А точнее сделал два отдельных create_generated_clock для каждого выхода PLL с ключем –add, дальше так же прописал set_input_delay. Но теперь мне не нравятся оба варианта…

Хотелось бы понять какой подход правильнее? И вообще, как лучше задать констрейны, для такого клока и входных данных с внешних устройств.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

Как то все это странно -   умножение по сути  выравнивает частоту генерируемого клока с точностью до фазы опорной и плыть частоты двух устройств не должны - но это конечно если все сделано с правильно. 

Если 2 внешних устройства умножают  клоки независимо и выдают  данные со своими клоками  то нет смысла  констрейнить их с привязкой к мастеру 24 MHz. По сути своей они есть независимые и асинхронные друг другу а также к мастеру. Тем более если вы не можете гарантировать жестких временных соотношений между ними при смене частот. 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
1 час назад, Kapsik сказал:

Хотелось бы понять какой подход правильнее? И вообще, как лучше задать констрейны, для такого клока и входных данных с внешних устройств.

Так навскидку.... Может я и не прав, но все же...

Есть PLL с нее частота куда-то поступает, что-то там с частотой происходит... Получается разомкнутый контур по частоте...

а ведь в PLL есть своя цепь регулировки и обратная связь по частоте... Так почему бы и не охватить это "куда-то" обратной связью? Т.е. обратную связь заводить не прямо с выхода PLL, а с той частоты, которая приходит  "откуда-то"...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
On 1/11/2019 at 2:32 PM, RobFPGA said:

Приветствую!

Как то все это странно -   умножение по сути  выравнивает частоту генерируемого клока с точностью до фазы опорной и плыть частоты двух устройств не должны - но это конечно если все сделано с правильно. 

Если 2 внешних устройства умножают  клоки независимо и выдают  данные со своими клоками  то нет смысла  констрейнить их с привязкой к мастеру 24 MHz. По сути своей они есть независимые и асинхронные друг другу а также к мастеру. Тем более если вы не можете гарантировать жестких временных соотношений между ними при смене частот. 

Удачи! Rob.

То есть моя первая мысль была правильная? Получается 4 асинхронных клока, на внешних устройствах виртуальные и в плис с ножек?

//verilog
	input wire					clk_dev_0_i  	, //клок с первого устройства
	input wire					clk_dev_1_i  	, //клок с второго устройства

	input wire [7:0]   			dev_0_data   	, //данные с первого устройства
	input wire 		   			strb_0_data   	, //строб с первого устройства

	input wire [7:0]   			dev_1_data   	, //данные с второго устройства
	input wire 		   			strb_1_data   	, //строб с второго устройства

 

#SDC
#клоки на пинах
create_clock -name {clk_dev_0_i} [get_ports {clk_dev_0_i}] -period 48MHz  
create_clock -name {clk_dev_1_i} [get_ports {clk_dev_1_i}] -period 48MHz

#клоки на внешних устройствах
create_clock -name virt_clk_dev_0_i -period 48MHz
create_clock -name virt_clk_dev_1_i -period 48MHz

#первое устройство
set_input_delay -clock { virt_clk_dev_0_i } -max 2  [get_ports {dev_0_data[*]}]
set_input_delay -clock { virt_clk_dev_0_i } -min -2 [get_ports {dev_0_data[*]}]

set_input_delay -clock { virt_clk_dev_0_i } -max 2  [get_ports {strb_0_data}]
set_input_delay -clock { virt_clk_dev_0_i } -min -2 [get_ports {strb_0_data}]

#второе устройство
set_input_delay -clock { virt_clk_dev_1_i } -max 2  [get_ports {dev_1_data[*]}]
set_input_delay -clock { virt_clk_dev_1_i } -min -2 [get_ports {dev_1_data[*]}]

set_input_delay -clock { virt_clk_dev_0_i } -max 2  [get_ports {strb_1_data}]
set_input_delay -clock { virt_clk_dev_0_i } -min -2 [get_ports {strb_1_data}]

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация