Setup и hold: почему метастабильность нельзя исправить

Тактовый сигнал обещает идеальный момент: в этот миг триггер берёт значение со входа. Кремний в это обещание не выполняет, и в datasheet у каждого триггера есть два окна вокруг фронта такта, внутри которых данные трогать нельзя. Нарушение этих окон — единственная ситуация в цифровой схеме, где вход может дать результат, которого на нём не было. Разберём, что именно обещают окна, что происходит при их нарушении и почему стандартное решение состоит из двух лишних триггеров. Как это окно вписывается в общую картину предмета, объясняется на странице «Схемотехника».

Такт — это момент, а не время

Сначала стоит уточнить то, из-за чего возникает вся проблема. Фронт тактового сигнала в datasheet показан вертикальной линией, и её легко принять за момент без длительности. На самом деле фронт занимает конечное время: у быстрых схем это доли пикосекунды, у медленных — единицы наносекунд. Внутри этого времени сигнал ещё не пришёл ни к какому определённому уровню, и «в этот момент схема должна прочитать ноль» не означает ничего, потому что момента там нет.

Отсюда правило, из которого растут все остальные: данные должны быть стабильны не в точке фронта, а в окне вокруг него. Нарушение на границе окна так же опасно, как нарушение в центре, потому что длительность фронта определяет, где именно проходит граница.

Два окна вокруг фронта

У триггера есть два параметра, и оба отвечают на разные вопросы. Setup — как долго данные должны быть готовы до фронта. Hold — как долго они должны оставаться готовыми после фронта. Оба значения заданы в datasheet и обычно лежат в диапазоне от долей пикосекунды до единиц наносекунд в зависимости от ячейки; конкретные числа всегда надо смотреть для своей микросхемы.

Данные устоялись: окна соблюдены фронт такта t setup t hold данные Данные изменились в окне: результат не гарантирован нарушен setup нарушен hold зона, где значение не имеет смысла CLK D
Сверху: данные меняются за пределами обоих окон, поэтому триггер читает заведомо верное значение. Снизу: оба изменения попали внутрь окон, и на выходе триггера может оказаться не то, что было на входе
ПараметрНа какой вопрос отвечаетЧто будет при нарушении
setupКак долго данные должны быть готовы до фронта тактаТриггер может взять старое или новое значение
holdКак долго данные должны быть готовы после фронтаТриггер может взять новое значение, хотя в момент фронта было старое
Длительность тактаСколько времени отводится всей комбинационной части между регистрамиСигнал не успевает устояться и тоже попадает в зону неопределённости
Запас по времениНасколько отличается суммарная задержка от периода тактаЧастые сбои, которые проявляются только в конкретной сборке

Обратите внимание на третью строку. Нарушить можно не только вход триггера, но и время, отведённое на комбинационную часть: если сигнал не успел устояться к моменту фронта, он попадает ровно в то же окно, только виноват не входной сигнал, а слишком короткий период такта. Из этого следует практическое правило: период такта выбирают не по скорости триггера, а по суммарной задержке всех вентилей между регистрами, с запасом. Сколько именно занимает задержка на вентиль, разобрано в статье про задержку распространения.

Метастабильность: что именно ломается

Нарушение окон не означает «выдастся противоположное значение». Оно означает «значение не имеет смысла», и это важное различие. Внутри триггера сигнал проходит через несколько инверторов, и когда данные меняются в неподходящий момент, напряжение на внутреннем узле останавливается между логическим нулём и логической единицей. Такой узел не принадлежит ни к одному из двух состояний, и время, которое схема проведёт в нём, случайно.

Отсюда три практических следствия, и они объясняют, почему тема выглядит тяжелее, чем должна быть. Первое: выход может показать значение, которого на входе не было, и это значение может продержаться дольше одного такта. Второе: заранее узнать, каким именно оно окажется, нельзя. Третье, и оно главное: повторить попытку на следующем такте не поможет, потому что фронт придёт к данным в тот же неподходящий момент. Метастабильность не лечится повторным чтением — её можно только обнаружить и дать время на разрешение.

Инженерная практика целиком построена на этом. Считают среднее время между отказами: сколько раз при заданной частоте и заданной длительности неопределённого окна триггер выйдет из метастабильного состояния не так, как ожидалось. Обычно этого достаточно, чтобы считать событие крайне редким, и вся конструкция сводится к одной мысли: дать время. Один такт — в подавляющем большинстве случаев достаточно; два такта — практически всегда достаточно.

Два триггера подряд: стандартное решение

Синхронизатор — это два D-триггера, тактируемых одним сигналом, между которыми стоит логическая цепочка без триггеров. Работает он так: первый триггер может на какое-то время выдать значение, которого на его входе не было, но, в отличие от одиночного триггера, это время ограничено и заканчивается в пределах одного такта. Второй триггер за этот такт успевает перейти в устойчивое состояние, и всё, что читает дальше, получает уже корректные данные.

Почему не одного? Формально можно рассчитывать и на один, но тогда вероятность попадания метастабильного значения дальше, в логику, перестаёт быть пренебрежимо малой. Почему не трёх? Третий триггер почти ничего не добавляет, а платит за это лишним тактом задержки и площадью: если два такта не хватило, то и три не помогут, потому что причина в окне, а не в количестве ступеней. Два триггера — это ровно столько, сколько нужно, чтобы время на разрешение было гарантировано.

Синхронизатор ставят на границе между тактовыми областями: там, где тактовые сигналы разных частот или фаз встречаются друг с другом. Внутри одной тактовой области метастабильность не возникает, и ставить там синхронизатор незачем. Для сигналов, которые не тактируются вовсе, тактируемых от внешнего источника или просто очень редких, одного триггера мало, и применяют согласование по уровню: событие «произошло» сбрасывает флаг, а флаг читается синхронно, что убирает и метастабильность, и потерю события. Так сделаны, например, флаги прерываний.

Как это выглядит в симуляторе

В симуляторе этого курса метастабильности нет, и это нужно понимать прямо, а не искать её в схеме. Симуляция трёхфазная: сначала все узлы вычисляют новое значение, затем все состояния фиксируются, потом изменения расходятся. Триггер на фазе фиксации берёт то, что в этот момент лежит на его входе, и никакого «между нулём и единицей» не возникает. В поведенческой модели нарушение setup выглядит не как неопределённость, а как решение: триггер честно берёт новое значение, потому что оно к моменту фиксации уже пришло.

Что из этого полезно. Модель корректно показывает главное правило синхронного дизайна: регистр берёт значение с входа только в момент такта, поэтому любые изменения входов между тактами для него не видны. Ошибку «прочитал раньше, чем посчитали» модель не воспроизводит, и это её достоинство: она заставляет решать задачу правильно, добавляя регистр, вместо того чтобы ловить редкий сбой. Плата за это — невозможность проверить тайминги в симуляторе: для них нужен анализ статического времени, и на программируемых логических схемах эту работу за вас делает инструмент, который сначала оценивает задержки, а затем подбирает безопасный период такта. Как это устроено на Tang Nano, разобрано в руководстве по Tang Nano.

Итог простой: в симуляторе проверяют логику, в datasheet проверяют окна, а на железе или в инструменте статического анализа проверяют время. Проверка только в одном из трёх мест даёт схему, которая работает у вас и не работает у других.

Что такое время установки (setup) и время удержания (hold)?

Setup — время, в течение которого данные на входе триггера должны быть стабильны до фронта тактового сигнала. Hold — время, в течение которого они должны оставаться стабильными после фронта. Оба значения заданы в datasheet микросхемы. Если данные меняются внутри этих окон, триггер не обещает правильное значение на выходе: оно становится неопределённым.

Что такое метастабильное состояние?

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

Зачем перед триггером ставят ещё один триггер?

Чтобы дать время на выход из метастабильного состояния. Первый триггер может какое-то время выдавать значение, которого не было на входе, но за один такт это время почти всегда заканчивается. Второй триггер, тактируемый тем же сигналом, за это время успевает перейти в устойчивое состояние, и всё, что читает дальше, уже корректно. Именно поэтому синхронизатор делают из двух триггеров, а не из одного.

Как избежать метастабильности в схеме с одним тактом?

Внутри одного тактового домена метастабильность не возникает: комбинационный сигнал успевает устояться задолго до фронта, если такт выбран с запасом. Проблема появляется там, где тактов несколько или где сигнал приходит извне: там нужен синхронизатор из двух триггеров, а для асинхронных событий — согласование по уровню или по фронту, чтобы схема не теряла и не дублировала события.

Проверьте себя

Почему нельзя бороться с метастабильностью повторным чтением на следующем такте?

Потому что причина повторяется. Данные приходят из другой тактовой области, и если фронт попал в окно один раз, то на следующем такте фронт снова окажется в неудобном положении относительно этих данных: задержка между областями не обязана быть кратна периоду. Повторное чтение помогает не тем, что «данные уже считались», а тем, что прошёл такт и время на разрешение истекло. Поэтому в синхронизаторе важен именно второй триггер, а не количество попыток.

Что будет, если тактировать второй триггер синхронизатора от другого тактового сигнала?

Смысл синхронизатора исчезнет. Он строится на том, что оба триггера смотрят на одни и те же входные данные в разные моменты одного и того же такта: разница моментов и есть время на разрешение. Если такты разные, вторая ступень не гарантирует, что состояние первого успело устояться, и метастабильность может перейти на следующую ступень. Общий такт для всей цепочки — не формальность, а условие работоспособности.

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

Потому что элементная база там фиксирована и описана производителем, а соединения и задержки определяет инструмент. Он оценивает самый длинный путь по задержке, сравнивает его с периодом такта и выбирает безопасную частоту либо, наоборот, сообщает, что схема не укладывается и нужен конвейер. Но окна по-прежнему действуют на границах, куда приходят внешние сигналы: там, где асинхронный вход становится синхронным, синхронизатор всё равно нужен и всё равно ставится вручную.

Как устроен сам триггер и почему он слышит только такт, разобрано в статье про такт и D-триггер, как читать саму временную диаграмму — в материале про временную диаграмму, а почему в процессоре всё разбито на регистры и комбинационные участки — в статье про комбинационную и последовательную логику.

Попробовать в симуляторе →