Я хочу рассказать об одной проблеме, которая встречается часто при разработке цифровых устройств, но о существовании которой многие забывают или даже вообще не подозревают.
Наши проекты для ПЛИС цифровые, большинство процессов внутри нее происходят синхронно с тактовой частотой подключенного генератора. Тем не менее, сама микросхема принимает сигналы из внешнего мира и часто эти сигналы асинхронны к нашей тактовой частоте.
Здесь возможны проблемы...
Предположим, что мы хотим «поймать» внешнее событие с помощью D-триггера. Такой триггер запоминает сигнал на входе D и выдает его на выход Q в момент положительного перепада (фронта) сигнала на входе C.
К сожалению (а может к счастью), в реальном мире события не происходят мгновенно. Сам фронт сигнала тактовой частоты немного растянут во времени, да и триггер переключается не мгновенно, на его переключение требуется время. Чтобы успешно зафиксировать входное значение в D-триггере входной сигнал должен быть стабилен некоторое время до фронта и после фронта тактовой частоты. Эти времена называются tsu (setup time) и th (hold time).
Так как рассматриваемый нами входной сигнал является асинхронным к тактовой частоте, то есть вероятность, что сигнал может начать меняться в момент фронта тактовой частоты. Это тот случай, когда не выдержанны времена tsu или th. На выходе триггера зафиксируется не ноль и не единица, а какое-то промежуточное значение.
Это состояние очень нестабильно. Известно, что триггер не сможет долго находиться в таком состоянии. Вероятность выхода триггера из метабильного состояния экспоненциально растет со временем.
В принципе, триггер сам выходит из метастабильного состояния через некоторое время tres (resolution time) из-за собственных внутренних шумов. Таким образом, это вопрос времени.
Существует некая замысловатая формула, позволяющая оценить, как часто происходит событие метастабильности. Есть такое понятие MTBF (Mean Time Between Failures) – время между «поломками».
- Fevent – частота входных событий.
- Fclk – тактовая частота на триггере.
- tres – время выхода триггера из метастабильного состояния (resolution time), зависит от технологии изготовления микросхемы.
- tff и Kff – так же коэффициенты связанные с технологией изготовления логических элементов и триггеров в микросхеме.
Чтобы уменьшить влияние возможной метастабильности в схему устройства вводят синхронизаторы. На самом деле – это просто два последовательных триггера.
Если первый триггер и «поймает» метастабильное состояние, то вероятно оно должно пройти к моменту фиксации сигнала во втором триггере. Понятно, что этот метод не избавляет от возможных проблем полностью, но зато он многократно уменьшает вероятность возникновения метастабильного состояния во втором триггере. После второго триггера мы можем с уверенностью считать, что сигнал будет всегда стабильным (либо «0», либо «1»).
Давайте посмотрим на проблему с практической стороны. Мы используем ПЛИС компании Altera и используем ее среду разработки Quartus II. Есть ли там какие-то средства диагностики метастабильных состояний? Может есть средства анализа проектов на предмет качества?
Оказывается, есть такое средство диагностики: Design Assistant. Выберем из меню среды Altera Quartus II пункты Assignments / Settings…
Найдем в категориях слева Design Assistant и включим его запуск установив флажек Run Design Assistant during compilation.
Теперь сделаем простейший проект:
Запускаем компиляцию и увидим, что никаких дополнительных особых предупреждений компилятор нам не выдает. Это из-за того, что он надеется, что входной сигнал data все таки является синхронным с сигналом clk.
Теперь усложняем проект:
Теперь уже у компилятора не может быть никаких сомнений по поводу природы входных сигналов. Тактирующий сигнал clk идет на первый триггер, а другой тактирующий сигнал clk2 идет на второй триггер. В проекте появилось две тактовой частоты. Если входной сигнал data фиксируется в первом триггере тактовой частотой clk, то понятно, что для второго триггера он прийдет асинхронным по отношению к частоте clk2. Данные передаются из одной части схемы, где работает частота clk, в другую часть схемы, где работает уже другая частота clk2. В иностранной литературе этот факт называется Crossing Clock Domains.
Запускаем компиляцию проекта и видим сообщение от Design Assistant:
Critical Warning: (High) Rule D101: Data bits are not synchronized when transferred between asynchronous clock domains. (Value defined:2). Found 1 asynchronous clock domain interface structure(s) related to this rule.
Таким образом, Quartus II говорит нам, что в проекте не все хорошо.
Добавляем в проект еще один триггер (synchronizer):
Компилируем, и вот, больше нет критического предупреждения от Design Assistant. Вот так и рекомендуется делать переход сигнала из одного Clock Domain в другой.
Заключение:
- Чем быстрее микросхема, тем меньше вероятность возникновения метастабильного состояния при фиксации в триггере асинхронного сигнала, так как ее параметры tsu и th меньше, чем у более медленной микросхемы.
- Чем выше тактовая частота на триггере и частота асинхронных входных событий, тем больше вероятность возникновения метастабильного состояния.
- При передаче данных из одного Clock Domain в другой обязательно использовать синхронизаторы – последовательно два (или более) триггера.
- Использование триггеров синхронизаторов вносит задержку при передаче сигнала, но с этим нужно просто мириться и нужно учитывать ее далее в проекте.
- Один асинхронный сигнал должен быть синхронизирован к тактовой частоте проекта только один раз.
Подробнее...