воскресенье, 18 июня 2017 г.

Gated clock в HDL

Что такое Gated clock (and/or signal ripple) и его последствия

Недавно занимался одним из своих старых проектов (Quartus 9.1) и, перечитывая, в очередной раз, предупреждения компиляции проекта, обнаружил, что появился такой интересный ворнинг : "Found 1 node(s) in clock paths which may be acting as ripple and or gated clocks -- node(s) analyzed as buffer(s) resulting in clock skew".  Данное предупреждение оказалось связано с моим модулем, управляющим работой двухканальным счетчиком (каждый из счетчиков работает попеременно), сам модуль формирует сигнал адреса и сигналы разрешения и сброса счетчиков.

Прежде всего попытаемся понять, что же означает данное предупреждение. А означает оно то, что на линии тактового сигнала (клока) присутствует логический вентиль (gate). Поскольку мы имеем дело с конкретной микросхемой, а не с математической функцией, то прохождение сигнала через логические элементы всякий раз будет добавлять задержку на время переключения вентиля из 0 в 1 или из 1 в 0. Другая часть предупреждения говорит о том, что наличие вентиля будет приводить к пульсациям. На самом деле, в этом случае могут быть проблемы с переключением на линии клока, например, время переключения вентиля 10 нс, на линии клока пришло переключение из 0 в 1 (posedge), за эти 10 нс, предположим клок переключился из 1 в 0 и, потом, снова из  0 в 1 непрерывно с малыми интервалами, так вот gated clock отфильтрует часть переключений и, как следствие, часть важной информации может быть потеряна.

Как же удалось этого добиться?

Сам удивляюсь как я смог спроектировать такую ерунду, но вот часть кода, описывающая мой модуль.

assign counter0_enable = ~counter_address;
 assign counter1_enable = counter_address;

d_trigger counter0_force_clear_trigger (.clk(counter0_enable), .data(vcc), .reset(counter0_reset), .enable(enable), .out(counter0_force_clear));
- d_trigger counter1_force_clear_trigger (.clk(counter1_enable), .data(vcc), .reset(counter1_reset), .enable(enable), .out(counter1_force_clear));

counter_address генерируется периодически по другому сигналу с помощью Т-триггера. Самое интересное, что к этому эффекту приводит генерация сигналов в counterХ_enable через триггер. И как же быть в такой ситуации? Почитав, что пишут в интернетах и немного подумав, я использовал для клока триггеров исходный сигнал, а операцию выбора работы триггера по адресу перенес в enable (т.е. force_clear сигналы генерируются только в моменты когда enable на триггерах равен 1):

d_trigger counter0_force_clear_trigger (.clk(~channel), .data(vcc), .reset(counter0_reset), .enable(enable & counter1_enable), .out(counter0_force_clear));
+ d_trigger counter1_force_clear_trigger (.clk(channel), .data(vcc), .reset(counter1_reset), .enable(enable & counter0_enable), .out(counter1_force_clear));
На RTL View данная ситуация (gated clock) проявляется следующим образом:










Согласно этому изображению, проблема в шунтировании двух D-триггеров гэйтами.

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



Комментариев нет:

Отправить комментарий

Распространение Windows-приложений (Chocolatey)

Менеджеры пакетов для ОС Windows В большинстве дистрибутивов Linux есть свои менеджеры пакетов: в Ubuntu/Mint это apt и deb, в OpenSuse э...