TimeQuest для чайников. Часть 4 (Как много интерфейсов разных)
- altera |
- constrains |
- TimeQuest |
- ПЛИС
System-Synchronus Input
Рассмотрим теперь тактирование АЦП от ПЛИС. В качестве примера возьмем параллельный АЦП AD9215. Положим что частота тактирования этого АЦП 100 МГц.
module adc (input clk, input [9 : 0] adc_dat, output adc_clk, output logic [9 : 0] data);
logic [9 : 0] adc_io_reg;
logic [9 : 0] adc_reg;
always_ff @(posedge clk) begin
{adc_reg, adc_io_reg} <= {adc_io_reg, adc_dat};
end
assign adc_clk = clk;
always_ff @(posedge clk) begin
data <= adc_reg;
end
endmodule
Начальный (как вы уже, наверное, поняли, в процессе ковыряния проекта, часто требуется рихтовка sdc файла) sdc файл такой
set_time_format -unit ns -decimal_places 3
derive_clock_uncertainty
create_clock -period 100MHz -name {clk} [get_ports {clk}]
create_generated_clock -name {adc_clk} -source [get_ports {clk}] [get_ports {adc_clk}]
set ADC_CLK_delay_max [expr 30.0*0.007]
set ADC_CLK_delay_min [expr 30.0*0.007]
set ADC_DATA_delay_max [expr 20.0*0.007]
set ADC_DATA_delay_min [expr 20.0*0.007]
set ADC_Tco_max 6.5
set ADC_Tco_min 2.5
set_input_delay -clock {adc_clk} -max [expr $ADC_CLK_delay_max + $ADC_Tco_max + $ADC_DATA_delay_max] [get_ports {adc_dat[*]}]
set_input_delay -clock {adc_clk} -min [expr $ADC_CLK_delay_min + $ADC_Tco_min + $ADC_DATA_delay_min] [get_ports {adc_dat[*]}]
О ужас, воскликнет кто-то, увидев кучу [expr] и много TCL переменных. Но мы то уже воробьи стрелянные, давайте разбираться что к чему.
set ADC_CLK_delay_max [expr 30.0*0.007]
set ADC_CLK_delay_min [expr 30.0*0.007]
Это задержка проводника тактовой частоты от ПЛИС до АЦП. Положим что на плате это проводник длинной 30мм, 0.007 нс/мм это оценочная задержка проводника 0.2мм на текстолите марки FR4. Можно было бы пересчитать в ручную, но лучше поручить эту работу TimeQuest.
set ADC_Tco_max 6.5
set ADC_Tco_min 2.5
А вот это уже параметры самого АЦП указанные в даташите. Я не использую типовое значение Tco, потому что нам нужно получить оценку для наихудшего случая. Теперь нам нужно прописать констрены tsu/th для триггеров в ПЛИС
set_input_delay -clock {adc_clk} -max [expr $ADC_CLK_delay_max + $ADC_Tco_max + $ADC_DATA_delay_max] [get_ports {adc_dat[*]}]
set_input_delay -clock {adc_clk} -min [expr $ADC_CLK_delay_min + $ADC_Tco_min + $ADC_DATA_delay_min] [get_ports {adc_dat[*]}]
Видно, что в эти констрейны входят задержки и параметры АЦП, соответствующие наихудшему случаю. Собираем, запускаем, смотрим.
Видим что констрейны выполнены, но запас по ним распределен не равномерно. Особенно настораживает маленький запас по tsu. Делаем Report Worst-Case Path и давайте смотреть в чем дело.
Мы видим на рисунке задержку от порта ПЛИС clk до порта ПЛИС adc_clk Clock Delay = 4.266нс, задержку сигнала на плате Input Delay = 6.85нс (недоверчивые могут посчитать так ли это, набрав на калькуляторе (30+20)*0.007 + 6.5) и задержку сигнала во входном I/O буфере Data Delay = 1.241нс. Все это составляет оценку прибытия данных в ПЛИС Data Arrival.
Теперь посмотрим на Data Required. Видим что анализ задержки начинается от второго фронта Latch Clock на приемном триггере ПЛИС (так и должно быть для анализа tsu) и задержка от порта ПЛИС clk до тактового входа триггеров adc_io_reg Clock Delay = 2.664нс. И относительно этого момента времени оценивается выполнение tsu на входном триггере ПЛИС.
Как поступить в этом случае? самый простой способ использовать PLL и подвинуть клок, на котором работают триггеры в ПЛИС. Мы это уже делали, можете проделать это у себя на тестовом проекте. Рассмотрим другой вариант как утоптать проект в констрейны, который часто используется - метод мультицикловых путей
Для этого инвертируем клок
assign adc_clk = ~clk;
И соответственно поправим sdc файл
create_generated_clock -name {adc_clk} -source [get_ports {clk}] -invert [get_ports {adc_clk}]
Все остальное остается тем же. Собираем, проверяем и в итоге
Видим что все в слаках. Посмотрим внимательнее что же произошло
Мы видим что точка отсчета tsu сдвинулась на 5нс влево, что естественно привело к ломке констейнов. Для того что бы эта картина стала больше похоже на действительность нужно передвинуть точку отсчета на второй фронт частоты Latch Clock. Для этого указываем TimeQuest что при анализе времянок нужно учитывать этот сдвиг.
set_multicycle_path -end -from {get_clocks {adc_clk}} -to {get_clocks {clk}} -setup 2
Т.е. я указал клок источник -from adc_clk, клок приемник -to clk, указал что анализ идет по setup и то что нужно учитывать второй фронт клока. А то, что этот фронт нужно применить именно к приемному клоку я указал с помощью ключа -end.
Теперь сбрасываем проект, запускаем анализ заново и
Видим что слаки ушли и запасы по th стали больше чем были запасы по tsu до этого. Хотя запас все же маловат. Но нам в этом случае важен сам метод. Посмотрим подробнее как идет анализ
Как видим точка отсчета сдвинулась на второй фронт. Как и было запланировано.
Вот собственно и все про данный вид интерфейсов. Как видите ничего сложного, нужно только обязательно учитывать разводку интерфейсов на печатной плате.
- блог пользователя des00
- 65432 просмотра
Новые записи в блогах
- Устранение дребезга контактов на основе вертикальных счетчиков
- Диагностика Imprecise Bus Faults в микроконтроллерах Cortex-M3/M4/M4F
- Self-powered камера
- Фоновый модулятор: беспроводная связь из ничего (перевод)
- Texas Instruments Analog Applications Journal SLYT612 "Снижение искажений в аналоговых КМОП ключах" (перевод)
- USB MSD. Часть 6. Команды SCSI (перевод)
- USB MSD. Часть 3. USB класс накопителей данных (перевод)
- Texas Instruments Application Report SBAA042 "Кодовые схемы, используемые в аналогово-цифровых преобразователях" (перевод)
- 10 принципов правильного интерфейса
- Релиз SDK на русский микропроцессор КРОЛИК
Комментарии
Спасибо Автору! Всё очень
Спасибо, поправил
Спасибо, поправил
Самоя первая картинка не
Самоя первая картинка не соответствует превью.(я так понимаю превью правильнее)
(уточнение) Самая первая
(уточнение)
Самая первая картинка на 3й странице не соответствует превью.(я так понимаю превью правильнее)
set_output_delay -clock
set_output_delay -clock [get_clocks {oclk}] -min -5.0 [get_ports {data[*]}]
как получается что мин делай отрицательная, как понять это физически????
я понимаю она вычислялась по формуле OmD = min tD (EXT) – tH (EXT) – max tCS (EXT),
Физически это понимается
Отправить комментарий