System-Synchronus Output
Рассмотрим вывод пилы на синхронный параллельный ЦАП.
module dac (input iclk, output oclk, output logic [7 : 0] data);
logic [7 : 0] cnt;
always_ff @(posedge iclk) begin
cnt <= cnt + 1'b1;
data <= cnt;
end
assign oclk = iclk;
endmodule
Положим параметры ЦАП tsu/th = 5ns/5ns, частота 10МГц, все настройки стоят по default. sdc файл для данного проекта будет таким.
set_time_format -unit ns -decimal_places 3
derive_clock_uncertainty
create_clock -period 10MHz -name {iclk} [get_ports {iclk}]
create_generated_clock -name {oclk} -source [get_ports {iclk}] [get_ports {oclk}]
set_output_delay -clock [get_clocks {oclk}] -max 5.0 [get_ports {data[*]}]
set_output_delay -clock [get_clocks {oclk}] -min -5.0 [get_ports {data[*]}]
Поясним, что означают незнакомые/непонятные для нас строки
set_time_format -unit ns -decimal_places 3
Мы задаем единицы измерения времени, что бы не писать их по месту.
create_generated_clock -name {oclk} -source [get_ports {iclk}] [get_ports {oclk}]
Это описание клока, на котором работает приемник нашего интерфейса (ЦАП). Как видно из кода, никаких преобразований с клоком не было, поэтому он назначен один в один.
set_output_delay -clock [get_clocks {oclk}] -max 5.0 [get_ports {data[*]}]
set_output_delay -clock [get_clocks {oclk}] -min -5.0 [get_ports {data[*]}]
Это описание констрейна связанное с tsu и th ЦАПа соответственно. По идее эти задержки должны задаваться как
Output maximum delay value = maximum trace delay for data + tSU of external register - minimum trace delay for clock
Output minimum delay = minimum trace delay for data - tH of external register – maximum trace delay for clock
Но в данном случае мы ими пренебрегаем. Положим, что задержки выровнены на плате. Всё, мы задали констрейны для нашего проекта. Собираем, запускаем анализ и видим в логах квартуса
Critical Warning: Timing requirements not met
Казалось бы всего 10МГц, как же так. Давайте разбираться подробно. Запускаем TimeQuest, выполняем анализ и видим результат
Нда, действительно не укладываемся во времянку. Давайте выясним почему. С помощью Report Worst Case Path смотрим что же происходит в интерфейсе.
По началу кажется, что на вейвформе изображен сплошной бред. Но не будем торопиться.
Смотрим внимательно, видно Launch Clock = iclk и Latch Clock = oclk. Они совпадают. Неужели TimeQuest забыл про задержку? А вот и нет, просто оба эти клока идут от входного порта ПЛИС iclk и временной анализ начинается с этой точки.
Смотрим далее. Видим Clock Delay = 2.394нс и Data Delay = 2.985нс. Clock Delay это задержка от порта ПЛИС iclk, до тактового входа триггера data[0]. А Data Delay это задержка от выхода триггера data[0] до порта плис data[0]. Сумма этих величин дает Data Arrival, т.е. задержку прибытия данных на порт плис.
Теперь смотрим, что происходит с клоком oclk. Чуть ниже видим Clock Delay = 3.766нс. Это и есть задержка клока oclk относительно клока iclk. Прибавляем к этому времени требуемое нам th (мы же не проходим по холду) и получаем Data Required. Как мы видим, а ведь действительно условие по th не выполняется.
А может быть TimeQuest врет, проверим задержку между портами iclk и oclk. Выполним task Report Path...

Действительно, не врет
Первое что приходит в голову, надо задержать данные, а задержка есть в I/O буферах. Посмотрим, используется ли она. С помощью Locate смотрим Resourse Property Editor
Упс, а триггер то не в IO буфере вообще, а без этого триггера сыклон 3 не умеет использовать задержку в I/O буфере. Назначаем на data[*] Fast Output Register. Проверяем и ...
Опять облом. Как же так, проверим ка квартус.
Он сделал все что мог, поставил триггер в I/О буфер, и даже использовал задержку (Output Pin Delay == 1). Но, "ну не шмогла я не шмогла" (с) Старый анекдот.
И тут мы вспоминаем, что, подав инверсный клок, мы поставим фронт как раз в середину данных, тогда tsu/th должны вылезти как бы автоматом. Пишем в коде
assign oclk = ~iclk;
В sdc файле
create_generated_clock -name {oclk} -invert -source [get_ports {iclk}] [get_ports {oclk}]
Вуаля, ошибок нет. И еще больше 40нс в запасе 
Вот в принципе и все про данный вид интерфейсов. От себя хочу добавить, что метод инверсии клока не является универсальным. И использовать его везде не следует.






Комментарии
Спасибо Автору! Всё очень
Спасибо, поправил
Спасибо, поправил
Отправить комментарий