Временные ограничения ASIC через SDC: как правильно указать часы с пульсациями?

Введение

Найдя в Интернете и на некоторых учебных курсах множество, иногда противоречивую или неполную информацию о том, как правильно создавать временные ограничения в формате SDC , я хотел бы попросить сообщество EE помочь с некоторыми общими структурами генерации часов, с которыми я столкнулся.

Я знаю, что существуют различия в том, как можно реализовать определенную функциональность на ASIC или FPGA (я работал с обоими), но я думаю, что должен быть общий, правильный способ ограничения времени данной структуры , независимо от базовая технология - пожалуйста, дайте мне знать, если я ошибаюсь.

Существуют также некоторые различия между различными инструментами для реализации и временного анализа разных поставщиков (несмотря на то, что Synopsys предлагает исходный код синтаксического анализатора SDC), но я надеюсь, что это в основном проблема синтаксиса, которую можно найти в документации.

См. также связанный с этим вопрос временных ограничений ASIC через SDC: как правильно указать мультиплексированные часы?

Вопрос

Речь идет о следующем делителе пульсирующих тактовых импульсов, который является частью модуля clkgen , который является частью более крупной конструкции, использующей генерирующие тактовые сигналы:

Делитель импульсных часов

Генерация clk0кажется относительно простой:

create_clock [get_pins clkgen/clk0] -name baseclk -period 500

Хотя я не уверен в командах SDC для сгенерированных, разделенных часов и clk2: Как указать параметры источника и цели ? Моя первоначальная мысль заключалась в том, что цель — это выходной контакт ячейки, генерирующей часы, а источник — как можно ближе к цели:clk4clk8

create_generated_clock -name div2clk -source [get_pins clkgen/divA/clk] -divide_by 2 [get_pins clkgen/divA/q]

Источником также может быть входной контакт модуля:

create_generated_clock -name div2clk -source [get_pins clkgen/clk0] -divide_by 2 [get_pins clkgen/divA/q]

Или ранее определенные исходные часы , как предлагается здесь :

create_generated_clock -name div2clk -source [get_clocks baseclk] -divide_by 2 [get_pins clkgen/divA/q]

... что также поднимает вопрос, должны ли исходные или целевые параметры быть чем-то отличным от get_pins, например get_nets, get_registersили get_ports.

Чтобы сделать пример как можно более общим, предположим, что сгенерированные часы и clk2могут управлять другими, потенциально взаимодействующими (пересекающимися доменами часов) регистрами (не показаны на схеме).clk4clk8

Я думаю, что ограничения для clk4и clk8должны быть очевидны, как только мы узнаем, как clk2пишется ограничение.

Экземпляр X1 (простой буфер) на схеме — это всего лишь заполнитель, чтобы подчеркнуть вопрос о том, где в сети распространения тактовых импульсов должна быть установлена ​​опция источникаcreate_generated_clock , поскольку инструменты автоматического размещения и маршрутизации обычно могут свободно размещать буферы в любом месте (например, как между divA1/qи divB1/clkконтакты).

Ответы (1)

Я бы сказал, что эмпирическое правило таково: установите либо входной порт верхнего модуля, либо вывод Q внутреннего триггера в качестве источника генерируемых часов.

Пример кода Verilog:

module top (

input clk,
input rst,

...

);

...

always @(posedge clk or negedge rst)
begin
if (rst == 1'b0) 
    div_2_clk = 1'b0;
else
    div_2_clk = ~div_2_clk;           
end

...

endmodule

Пример кода SDC:

create_clock -name clk -period 5 [get_port clk]
...
create_generated_clock -name slow_clk -source [get_port clk] -divide_by 2 [get_pins div_2_clk_reg/Q]

Я не тестировал приведенный выше синтаксис. Также обратите внимание на расширение, _regдобавленное к имени RTL сигнала — это расширение, добавляемое инструментом синтеза, когда он обнаруживает, что сигнал должен быть представлен триггером. Это расширение может различаться между инструментами (я точно не знаю).

Если вы используете какую-либо оболочку RTL для триггеров, установите источником генерируемых часов внутренний вывод Q триггера, а не выходной контакт оболочки.

Если вы следуете этим простым правилам, вам не нужно беспокоиться о каких-либо буферах, добавленных инструментами синтеза или P&R.

Спасибо за Ваш ответ! Означает ли это, что анализатор времени добавит задержки пути (и потенциально вставленного буфера) к задержке (сгенерированных) часов? Должна ли моя первая линия SDC быть create_clock [get_ports clk0]вместо этого (при условии , что clk0это порт верхнего уровня)? Если бы вы могли включить это в свой ответ, а также включить хотя бы один полный пример create_generated_clockутверждения, я был бы рад принять его!
@FriendFX, я добавил несколько фрагментов кода, но относитесь к ним осторожно - они не проверены.
спасибо за фрагмент SDC (не нужен Verilog). Для create_*clockкоманд означает ли это, что анализатор времени добавит задержки пути (и потенциально вставленного буфера) к задержке (сгенерированных) часов?
@FriendFX, что вы подразумеваете под «задержкой (сгенерированных) часов»? Задержка относительно чего? Его исходные часы? Если да, то вас, вероятно, интересует что-то, связанное с пересечением доменов часов между этими часами?
Я имел в виду, будет ли задержка пути от sourceсгенерированных targetчасов включать какие-либо буферы, которые инструмент P&R может вставить между этими узлами?
@FriendFX, я не уверен, что смогу ответить на этот вопрос, не понимая, почему вас интересует задержка между этими часами. В общем, как только вы выполните временной анализ схемы P&R, все задержки будут учтены в дереве часов (буферы, мультиплексоры, высокоразветвленные сети и т. д.).
Единственное, что меня беспокоило, это то, что я прочитал в Best Practices for Quartus II TimeQuest Timing Analyzer , что « -sourceопция должна ссылаться на ближайший тактовый вывод указанной цели » . в этом случае эту -master_clockопцию можно использовать в любом случае. Я просто хочу убедиться, что я не мешаю анализатору времени правильно учитывать все задержки.
Что касается вашего вопроса «почему вас интересует задержка между этими часами»: если в моем примере есть какие-либо пути данных между регистрами между регистрами clk0и clk4, любые задержки в сети часов между clk0и clk4должны учитываться по времени анализатор этих путей, я прав?
@FriendFX, я не могу ответить на конкретный вопрос Quartus, потому что я никогда не использовал ПЛИС Altera. Если у вас есть путь между регистрами clk0и clk4, вы либо определите его как ложный путь (если часы взаимоисключающие, если вы используете синхронизаторы,...), либо как многоцикловый путь. В первом случае инструмент не должен выполнять какой-либо временной анализ, и вы должны убедиться, что логический сбой не может произойти. В последнем случае все соответствующие задержки были учтены другими инструментами, которые я видел.
Я также не хочу быть специфичным для Quartus. К сожалению, я не нашел никаких других (связанных с ASIC) ресурсов SDC, которые хотя бы вдавались в эти подробности — любые указатели будут оценены! Я надеюсь, что SDC будут достаточно универсальными, чтобы их можно было применять к инструментам и потокам, как упоминалось в моем первоначальном вопросе.
@FriendFX, у меня нет хороших рекомендаций, чтобы дать вам. Попробуйте найти Synopsis Design Compiler User's Guide — я подозреваю, что это источник самой полной документации.
Я нашел его здесь , но, к сожалению, он не дает никаких подробностей о команде create_generated_clockSDC. Я принял твой ответ. Возможно, когда-нибудь я начну отдельный вопрос о деталях -sourceопции. Спасибо за ваши старания!