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

Прошу помощи с констрейнами DDR/QDR

set_input_delay -max $skew -clock [get_clocks virtual_clock] [get_ports {ADC1_D[*]}]
set_input_delay -max $skew -clock [get_clocks virtual_clock] -clock_fall [get_ports {ADC1_D[*]}] -add_delay
set_input_delay -min -$skew -clock [get_clocks virtual_clock] [get_ports {ADC1_D[*]}] -add_delay
set_input_delay -min -$skew -clock [get_clocks virtual_clock] -clock_fall [get_ports {ADC1_D[*]}] -add_delay

Не уверен что это имеет отношение к данной теме, но всегда думал что для set_input_delay параметр -max это величина равная половине периода минус tsetup (для DDR).

А у Вас и для -min и для -max одно и тоже $skew и почему-то с минусом для -min.

И вот здесь

set_input_delay -min -$skew -clock [get_clocks virtual_clock] [get_ports {ADC1_D[*]}] -add_delay

-add_delay по моему не нужен

Изменено пользователем Freibier

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


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

1 час назад, Freibier сказал:

-add_delay по моему не нужен

Так как это DDR, то add_delay нужен для задания ограничений заднего фронта. Он записан вместе с -clock_fall 

 

1 час назад, Freibier сказал:

А у Вас и для -min и для -max одно и тоже $skew и почему-то с минусом для -min.

Тоже есть по этому поводу сомнения. Но у меня с выхода АЦП валидные данные выровнены относительно фронта тактового импульса. И я описываю, что launch clock будет виртуальный, и соответствует с началом шкалы, а latch clock (ADC1_CLK) физический и он приходит смещённый относительно данных и начала шкалы на 90 градусов.  В случае если описывать set_input_delay относительно  latch clock (ADC1_CLK), то да, -max должен быть, как вы и написали,  <половине периода - tsetup > .

 

Кстати, а не может ли быть проблема из-за того, что в моём случае клок не может прийти на триггер раньше чем данные ? Минимально возможный путь клока до регистра 3 нс, а данные 1.5 нс. Т.е. защёлкиваемые данные будут анализироваться со сдвигом на один такт  И как это описать в таком случае ? 

 

Пробовал так, ошибки уходят, но работать от этого не начинает. Это правильная запись ?
set_multicycle_path 2 -setup -from [get_clocks virtual_clock_adc] -to [get_clocks {ADC1_CLK} ]
set_multicycle_path 1 -hold -from [get_clocks virtual_clock_adc] -to [get_clocks {ADC1_CLK} ]

Ещё в догонку. Я указал set_input_delay -clock virtual_clock_adc -max [expr $adc_data_period/2 - $dv_bfe] ну и все остальные, как в примерах  SDC от Xilinx, анализатор выдал вот такую картину. То есть запас по slack 3 нс, при периоде 2.5 нс. Т.е он ожидает данные на следующем периоде, а приходят они на период раньше и это для него нормально. Как такое может быть ?

image.thumb.png.b72027335df8afa0797c6d0ceb5f7d30.png

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


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

23 minutes ago, Digi said:

защёлкиваемые данные будут анализироваться со сдвигом на один такт  И как это описать в таком случае

мультицикл. НО! Разработчик ясно должен себе представлять, в какой такт он получит в регистре валидные данные, а не мусор.

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


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

3 минуты назад, Yuri124 сказал:

мультицикл. НО! Разработчик ясно должен себе представлять, в какой такт он получит в регистре валидные данные, а не мусор.

Я ожидаю получить на входе ADC_D[*] валидные данные не позднее 0,3 нс и не ранее 0,3 нс относительно фронтов виртуального клока. В каком периоде клока - не важно, но для всех каналов должно быть одинаково. Фактически для всех каналов это реализуемо на втором или третьем периоде клока. Но для начала в этом простом проекте с одним каналом не могу правильно описать то что хочу

 

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


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

Вроде ситуация у всех наверное такая встречалась, или я один на такие грабли наступил ? Кто как описывал QDR интерфейс ?

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


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

1 час назад, Digi сказал:

Так как это DDR, то add_delay нужен для задания ограничений заднего фронта. Он записан вместе с -clock_fall 

Так в той строке которую я процитировал -clock_fall нет, а -add_delay есть. Может это и не важно ...

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


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

17 hours ago, Digi said:

Вроде ситуация у всех наверное такая встречалась, или я один на такие грабли наступил ? Кто как описывал QDR интерфейс ?

вы сделайте проще, что бы не угадывать что и как, возьмите упрощенный проект и выложите qar файл, так всем можно будет позырить что у вас там в коде, что с ограничениями и куда. ну и название АЦП в теме я не увидел.

ЗЫ. а прибить гвозядями это все эти пути в false path и руками задать задержки. Можно еще руками прибить целлы к чипу.

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


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

Выкладываю тестовый проект. АЦП ADC42LB69. ПЛИС Cyclone 10GX. Ouartus 20.4 Prime

1 час назад, des00 сказал:

Можно еще руками прибить целлы к чипу.

Как это правильно сделать ?

ADC_QDR_test.qar

image.thumb.png.2ee098fa9f3af0a5009447c4cd94711c.png

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


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

1 hour ago, Digi said:

Как это правильно сделать ?

недавно где то обсуждалось Back Annotation в квартусе, самому никогда не надо было

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


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

15.1 квартус не хочет раскрывать( тогда можно выложить сорцы? 

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


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

Переделал проект под обычные регистры. По идее должно работать так же как и Intel GPIO Half-Rate. 

 

ADC1_D[*] - поток данных DDR выставляется на частоте 400 МГц 0 градусов.
ADC1_CLK - 400 МГЦ (90 градусов)
ADC1_FRM - 200 МГц (0 градусов)

 

Структура такая: 

image.thumb.png.1599fd3b55f134179dc3403d876b86e1.png

Проект для Q15 qddr.qar

SDC:
 

set_time_format -unit ns -decimal_places 3
derive_clock_uncertainty 

set adc_data_period 2.500
set adc_frame_preiod [expr $adc_data_period * 2]


create_clock -name virtual_clock_adc -period $adc_data_period  
create_clock -name {ADC1_CLK} -period $adc_data_period   [get_ports  {ADC1_CLK}]  -waveform { 0.625 1.875 }

create_clock -name {ADC1_FRM} -period $adc_frame_preiod  [get_ports {ADC1_FRM}] 

set_clock_groups -exclusive -group [get_clocks  {ADC1_CLK ADC2_CLK virtual_clock_adc ADC1_FRM ADC2_FRM } ] 
#set_clock_groups -exclusive -group [get_clocks  {ADC1_CLK virtual_clock_adc ADC1_FRM } ] 
#set_clock_groups -exclusive -group [get_clocks  {ADC2_CLK virtual_clock_adc ADC2_FRM } ] 



# Edge-Aligned Dual Data Rate Source Synchronous Inputs
# (Using a direct FF connection)
#
# For an edge-aligned Source Synchronous interface, the clock
# transition occurs at the same time as the data transitions.
# In this template, the clock is aligned with the beginning of the
# data. The constraints below rely on the default timing
# analysis (setup = 1/2 cycle, hold = 0 cycle).
#
# input            _________________________________
# clock  _________|                                 |___________________________
#                 |                                 |                 
#         skew_bre|skew_are                 skew_bfe|skew_afe
#         <------>|<------>                 <------>|<------>
#        _        |        _________________        |        _________________
# data   _XXXXXXXXXXXXXXXXX____Rise_Data____XXXXXXXXXXXXXXXXX____Fall_Data____XX
#

set skew_bre           0.200;             # Data invalid before the rising clock edge
set skew_are            0.200;             # Data invalid after the rising clock edge
set skew_bfe           0.200;             # Data invalid before the falling clock edge
set skew_afe            0.200;             # Data invalid after the falling clock edge

# Input Delay Constraint 
set_input_delay -clock virtual_clock_adc -max [expr $adc_data_period/2 + $skew_afe] [get_ports {ADC1_D[*]}];
set_input_delay -clock virtual_clock_adc -min [expr $adc_data_period/2 - $skew_bfe] [get_ports {ADC1_D[*]}];
set_input_delay -clock virtual_clock_adc -max [expr $adc_data_period/2 + $skew_are] [get_ports {ADC1_D[*]}] -clock_fall -add_delay;
set_input_delay -clock virtual_clock_adc -min [expr $adc_data_period/2 - $skew_bre] [get_ports {ADC1_D[*]}] -clock_fall -add_delay;

# ************** False path *****************

set_false_path -setup -fall_from [get_clocks virtual_clock_adc] -rise_to [get_clocks ADC1_CLK]
set_false_path -setup -rise_from [get_clocks virtual_clock_adc] -fall_to [get_clocks ADC1_CLK]
set_false_path -hold -rise_from [get_clocks virtual_clock_adc] -rise_to [get_clocks ADC1_CLK]
set_false_path -hold -fall_from [get_clocks virtual_clock_adc] -fall_to [get_clocks ADC1_CLK]

 

Verilog:
 


module top 
(

	//ADS42LB69 

	// ADC1
	input		[3: 0]		ADC1_D,	
	input 					ADC1_CLK,
	input 					ADC1_FRM,

		
	// ADC2
	input		[3: 0] 		ADC2_D,
	input 					ADC2_CLK,
	input 					ADC2_FRM,
	
	output	[15:0]		ADC1_OUT,				
	output	[15:0]		ADC2_OUT

);

reg 	[3:0]	a1_regout_hi;
reg 	[3:0]	a1_regout_lo;
reg 	[3:0]	a1_regout_lo_n;

reg 	[7:0]	a1_hr_regout_hi;
reg 	[7:0]	a1_hr_regout_lo;
reg 	[7:0]	a1_hr_regout_lo_n;



wire [15: 0] gpio1_d;
wire [15: 0] gpio2_d;

//---- Full rate latch ----
always @(posedge ADC1_CLK)
begin
	a1_regout_hi[3:0] <= ADC1_D[3:0];
	a1_regout_lo[3:0] <= a1_regout_lo_n[3:0];
end

always @(negedge ADC1_CLK)	
	a1_regout_lo_n[3:0] <= ADC1_D[3:0];


//------- Half rate latch ------	
always @(posedge ADC1_FRM)
begin
	a1_hr_regout_hi[7:0] <= {a1_regout_hi[3:0], a1_regout_lo[3:0]};
	a1_hr_regout_lo[7:0] <= a1_hr_regout_lo_n[7:0];
end

always @(negedge ADC1_FRM)	
	a1_hr_regout_lo_n[7:0] <= {a1_regout_hi[3:0], a1_regout_lo[3:0]};

//------------------------------

	
assign ADC1_OUT[15:0] = {a1_hr_regout_hi[7:0] , a1_hr_regout_lo[7:0] };


 

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


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

Вы пишете :

Цитата

ADC1_D[*] - поток данных DDR выставляется на частоте 400 МГц 0 градусов.
ADC1_CLK - 400 МГЦ (90 градусов)

т.е. фронт клока находится в центре окна данных.

А констрейны для варианта когда данные между фронтами.

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


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

# ADC1_CLK                          _________________________________ 
#       ___________________________|                                 |___________________________ 

# virtual clock    _________________________________
#        _________|                                 |___________________________
#                 |                                 |                 
#         skew_bre|skew_are                 skew_bfe|skew_afe
#         <------>|<------>                 <------>|<------>
#        _        |        _________________        |        _________________
# data   _XXXXXXXXXXXXXXXXX____Rise_Data____XXXXXXXXXXXXXXXXX____Fall_Data____XX
#

set skew_bre           0.200;             # Data invalid before the rising clock edge
set skew_are            0.200;             # Data invalid after the rising clock edge
set skew_bfe           0.200;             # Data invalid before the falling clock edge
set skew_afe            0.200;             # Data invalid after the falling clock edge

# Input Delay Constraint 
set_input_delay -clock virtual_clock_adc -max [expr $adc_data_period/2 + $skew_afe] [get_ports {ADC1_D[*]}];

 

set_input_delay указывал относительно virtual clock

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

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


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

Может я конечно чего и не понимаю, с такими ОГРОМНЫМИ частотами не приходилось сталкиваться и вообще я только учусь, но

вот же на диаграмме видно что фронт клока находится в середине окна данных и констрейн должен быть

set_input_delay -clock virtual_clock_adc -max [expr $adc_data_period/2 (минус) tSETUP] ...

set_input_delay -clock virtual_clock_adc -min [expr $adc_data_period/2 (плюс) tHOLD] ...

2.thumb.jpg.d0098152515858e643a0a95f1eaa91ef.jpg

И опять этот, непонятный мне, виртуальный клок... )

Изменено пользователем Freibier

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


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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...