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

    

TimeQuest, кто ж тебя выдумал?

Возясь со своим реальным проектом, сделал простой учебный. Пытаюсь разобраться в констрейнах (хотя некогда считал себя достаточно грамотным в этой теме).

Вот SystemVerilog проект. Ниже - констрейны для него. Работаю в Quartus 13.1, ПЛИС EP3C5E144I7.

module ClockDivider (
    (* chip_pin = "84" *)    input    ResetN,
    (* chip_pin = "89", altera_attribute = "-name io_standard lvds" *) input ClkIn,
    (* chip_pin = "28" *)    output    ClkOut,
    (* chip_pin = "30" *)    input    ClkSel,
    (* chip_pin = "32" *)    input    DataIn,
    (* chip_pin = "33" *)    output    DataOut
);

    bit        ClkDiv;
    always_ff @(posedge ClkIn, negedge ResetN)
        if (!ResetN)    ClkDiv <= 0;
        else            ClkDiv <= !ClkDiv;

    always_comb
        if (!ClkSel)    ClkOut = ClkIn;
        else            ClkOut = ClkDiv;
    
    always_ff @(posedge ClkOut, negedge ResetN)
        if (!ResetN)    DataOut <= 0;
        else            DataOut <= DataIn;

endmodule : ClockDivider

 

set_time_format -unit ns -decimal_places 3

create_clock -name clk_in -period "100 MHz" -waveform {0 5.0} ClkIn

create_clock -name clk_virt -period "100 MHz"

create_generated_clock -name clk_div ClkDiv -divide_by 2 -source ClkIn

# derive_clocks

derive_clock_uncertainty

set_input_delay -clock clk_virt -min 0.0 ClkSel
set_input_delay -clock clk_virt -max 1.0 ClkSel

set_input_delay -clock clk_virt -min 0.0 ResetN
set_input_delay -clock clk_virt -max 1.0 ResetN

set_input_delay -clock clk_virt -min 0.0 DataIn
set_input_delay -clock clk_virt -max 1.0 DataIn

set_output_delay -clock clk_virt -min -2.0 ClkOut
set_output_delay -clock clk_virt -max -1.0 ClkOut

set_output_delay -clock clk_virt -min -2.0 DataOut
set_output_delay -clock clk_virt -max -1.0 DataOut

Вопросы.

Почему работает описание триггера - делителя тактовой частоты, просто делить частоту на 2, без задержек в самом триггере? Как учитываются задержки в триггере?

Почему для выходных сигналов пришлось сделать отрицательную задержку, иначе ограничения не выполнялись?

Когда смотрел в TimeQuest временнЫе пути, Launch Clock запускался по срезу. Прикладываю картину ниже.

Правильные ли вообще эти констрейны?

Любые советы почитаю с интересом. (К сожалению, ответить смогу только завтра, ибо предстоит культурное мероприятие).

 

Вот картина-отчет. Как ее интерпретировать?

 

Нужно ли описывать сигнал после мультиплексора как тактовый? Пишут, вроде, нужно. А что же TimeQuest не ругается?

post-10362-1515322664_thumb.jpg

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


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

А разве не надо писать констрейн между вашим клоком и виртуальным ?

set_clock_groups -exclusive -group ?

И ещё немаловажный вопрос :применил ли Quartus для выходных сигналов fast output registers ? На сколько мне известно без этих регистров не работает специальный блок, регулирующий задержки.

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


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

Виртуальные такты - всегда снаружи ПЛИС. Ничего больше не надо.

По второму вопросу уже не скажу. Для данных - мог бы.

 

Вот для тактов в мультиплексоре группа нужна, думаю.

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


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

Почему работает описание триггера - делителя тактовой частоты, просто делить частоту на 2, без задержек в самом триггере? Как учитываются задержки в триггере?

 

Получаемую тактовую частоту вы уже описали с помощью create_generated_clock

 

Задержка в триггере учитывается при расчете максимально возможной частоты проекта.

post-77312-1515339837.png

post-77312-1515339929_thumb.png

 

В данном случае это время Tq clk

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


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

Видимо, Tclk-q?

Эти времена понятны. Но разве я их описывал? Задал такты после триггера, совпадающие по фронтам с входными. А реально это не так.

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


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

текст, помеченный тегами [ b ] [ /b ] - моя писанина.

module ClockDivider (  [b] // Блин эти аттрибуты бы вывести нахрен в топ-левел. и в топ-левел должны остаться только связи между модулями. никакой логики, а то это какой-то базар-вокзал.[/b]
                                 [b] // хуже того, заранее становится проблемой, к чему конкретно привяжутся констрейны. как обычно беда в названиях и их поиске и назначении констрейнов[/b]
                                [b] // на соответствующие физические ячейки квартусом. всё не найденное будет проигнорировано.[/b]
    (* chip_pin = "84" *)    input    ResetN,
    (* chip_pin = "89", altera_attribute = "-name io_standard lvds" *) input ClkIn,                              [b] // вот это я так понимаю фигня из соседней темы[/b]
    (* chip_pin = "28" *)    output    ClkOut,
    (* chip_pin = "30" *)    input    ClkSel,
    (* chip_pin = "32" *)    input    DataIn,
    (* chip_pin = "33" *)    output    DataOut
);

    bit        ClkDiv;
    always_ff @(posedge ClkIn, negedge ResetN)
        if (!ResetN)    ClkDiv <= 0;
        else            ClkDiv <= !ClkDiv;                      [b]// тут видно что ClkDiv тикает от ClkIn. ок. заделили пополам. ставим себе пометку - на температуре поплывёт.[/b]

    always_comb
        if (!ClkSel)    ClkOut = ClkIn;                         [b]// тут видна достаточно конкретная жопа в случае с насасыванием со входа ClkSel "иголок" и прочего мусора[/b]
        else            ClkOut = ClkDiv;                         [b]// если нужно стабильное поведение, ClkSel должен быть предварительно прорегистрен, хотя бы через double-flop[/b]
                                                                            [b]// далее, тут же видна жопа с моментом переключения из одного состояния в другое. следующим блокам просто необходим сигнал сброса при таком переключении[/b]
                                                                             [b]// если всё же необходимо изменять частоту без сброса, есть специальные техники glitch-free clock switching[/b]
    
    always_ff @(posedge ClkOut, negedge ResetN)
        if (!ResetN)    DataOut <= 0;
        else            DataOut <= DataIn;                   [b]// тут видно что DataOut тикает вместе с DataIn по ClkOut. в принципе тоже ок, но будет нормально работать только [/b]
                                                                          [b]// при отсутствии "иголок" и glitch-free переключениях частоты при помощи ClkSel)[/b]

endmodule : ClockDivider

 

set_time_format -unit ns -decimal_places 3

create_clock -name clk_in -period "100 MHz" -waveform {0 5.0} ClkIn  [b]# OK. здесь квартус действительно увидит что 100 МГц действительно зашло на вход ClkIn.[/b]

create_clock -name clk_virt -period "100 MHz"                                     [b]# OK. создали "нечто" никуда не назначенное.[/b]

create_generated_clock -name clk_div ClkDiv -divide_by 2 -source ClkIn [b]# OK. тактовую создали, название дали, источник показали. куда она дальше расходится будет - квартус не поймёт. нужна будет ещё одна подсказка.[/b]

# derive_clocks

derive_clock_uncertainty [b]# приняли значения по умолчанию из шаблона конкретной модели ПЛИС. ОК.[/b]

set_input_delay -clock clk_virt -min 0.0 ClkSel [b]# не понятно что имелось ввиду # здесь фактически указано, что снаружи ПЛИС задержка от 0 до 1 нс[/b]
set_input_delay -clock clk_virt -max 1.0 ClkSel [b]# поэтому нужно скорректировать её на внутренней логике от пинов  до входов always_ff и always_comb где-то внутри по ресурсам ПЛИС[/b]
                                                                      [b]# но поскольку clk_virt ни к чему не привязан, квартус ничего не понимает[/b]

set_input_delay -clock clk_virt -min 0.0 ResetN [b]# аналогично не понятно что имелось ввиду[/b]
set_input_delay -clock clk_virt -max 1.0 ResetN

set_input_delay -clock clk_virt -min 0.0 DataIn [b]# аналогично не понятно что имелось ввиду[/b]
set_input_delay -clock clk_virt -max 1.0 DataIn

set_output_delay -clock clk_virt -min -2.0 ClkOut [b]# аналогично не понятно что имелось ввиду[/b]
set_output_delay -clock clk_virt -max -1.0 ClkOut

set_output_delay -clock clk_virt -min -2.0 DataOut [b]# аналогично не понятно что имелось ввиду[/b]
set_output_delay -clock clk_virt -max -1.0 DataOut

 

с учетом вышесказанного - "более-менее" это хозяйство будет работать на частоте не выше 5...10 МГц.

Для 100/50 придётся переделывать.

на ClkOut констрейн не назначился - квартус его не нашел, возможно, из-за больших/маленьких букв, возможно из-за того что всё это в топ-модуле (или нет? отсюда не видно) поэтому на DataOut будет фигня от сборки к сборке.

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


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

Вообще, если я не ошибаюсь то для мультиплексирования клоков если уж без него никак не обойтись то надо применять специальный модуль, генерируемый мегавиззардом ALTCLKCTRL.

Но там есть засада, что какие-то входы можно подключить только к PLL.

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


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

krux, по делу есть чего сказать?

Это и есть top.

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

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


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

А можно уточняющий вопрос ?

Задача учебного проекта - научиться правильно констрейнить выходные сигналы с учётом мультиплексирвания клоков ?

По умолчанию считать, что проект не имеет глитчей ?

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


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

Пример плохой, потому что мультиплексор клоков в нем описывать не требуется. И виртуальный клок не нужен - все порты достаточно относительно ClkIn констрейнить (кроме DataOut, если он синхронен ClkOut).

p.s.

Соврал. Нужен констрейнт -генерейтед клок на выходе триггера-делителя, иначе через него latency считаться не будет

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


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

ViKo

по делу - выкинуть и переписать.

 

но для начала понять, сможете ли использовать CLKCTRL. т.е. сможете ли кинуть внешнюю (с пина на пин) петлю.

дальше законстрейнить этот входной CLKCTRL под две тактовые.

дальше по обстоятельствам

 

зы. я в одном своем проекте делал переключение 2,5/25/125 МГц при помощи glitch-free схемы, работало нормально. проблемы были с hold-ами на низких температурах, решилось небольшим пайплайном.

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


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

Жажду увидеть правильные констрейны. Выкинуть любой дурак умеет, а переписать - не любой.

Какой-такой CLKCTRL?

 

А можно уточняющий вопрос ?

Задача учебного проекта - научиться правильно констрейнить выходные сигналы с учётом мультиплексирвания клоков ?

По умолчанию считать, что проект не имеет глитчей ?

Да, пишем констрейны для проекта. А именно - ripple clock, multiplexed clock, source-synchronised project.

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


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

я понял в чем проблема, в вашем чипе CLKCTRL так как я думал, работать не будет:

https://www.altera.com/content/dam/altera-w...3_ciii51006.pdf

слегка противный осадочек, когда понимаешь, что -1 поколение назад не всё было так прекрасно.

 

тогда надо делать glitch-free clock switching, с выводом результата опять-таки на внешний пин, и закольцовыванием его снаружи. и констрейнить закольцованный входящий клок одновременно по всем правилам (сколько вариантов частот - столько и констрейнов).

выводить можно куда угодно, заводить как обычно на GCLK

 

заодно если при переключениях будут ошибки - сможете осциллом найти, ибо сигналтапом это нереально.

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


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

Насчет виртуальных тактов. Уже выбросил, заменил на те же входные ClkIn. TimeQuest съел.

Однако сейчас вычитал в Timing Analizer Cookbook.

All input and output delays should reference a virtual clock. With that virtual clock, the Timing Analyzer

can derive and apply the correct clock uncertainty values when you use the derive_clock_uncertainty

command. If the input and output delays reference base clocks or PLL clocks rather than virtual clocks, the

intra- and inter-clock transfer clock uncertainties, determined by derive_clock_uncertainty , are

incorrectly applied to the I/O ports. Also, with virtual clocks, additional external clock uncertainties can

be applied independent of the clock uncertainties determined by derive_clock_uncertainty.

Так что, ребята, виртуальные такты нужны.

P.S. Проверил. С виртуальными тактами резервы времени меньше (более отрицательные, когда не укладываются, а именно -2.351 vs -2.332 ns).

 

Насчет групп тактов для мультиплексора. Задал

set_clock_groups -exclusive -group {clk_in} -group {clk_div}

Теперь диапазон рабочих задержек другой, более широкий. Положительные числа работают (не всякие).

 

Однако, так и не понял, почему при анализе используется срез Launch Clock clk_in.

Также нигде не увидел объяснения, почему для триггера можно задать делитель на 2 без учета задержек в нем. Не укладывается в голове.

 

Продолжаю копаться.

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


Ссылка на сообщение
Поделиться на другие сайты
Однако, так и не понял, почему при анализе используется срез Launch Clock clk_in.

Кстати вопрос интересный. У меня ситуация аналогичная !

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


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

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

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

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

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

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

Войти

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

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