Clock Enable - что может быть проще?

топ 100 блогов nabbla108.11.2025 В заметке Безумный MAX3032: зазеркалье отрицательных фронтов мы разобрали схему D-триггера со срабатыванием по фронту, реализованную на КМОП элементах. Правда, её предпочитают чуточку перекомпоновать - транзисторов остаётся столько же, но задержка от фронта тактовой частоты до выдачи нового значения на выходе снижается. Под катом покажу этот вариант.

Данный драндулет иногда сокращённо называют DFF - D Flip Flop. В английской терминологии различают Flip Flop (FF), это когда срабатывает по фронту, и Latch, когда просто по уровню. У нас последний тоже зовут триггер-защёлка, иногда: прозрачный триггер (поскольку когда C=1, он просто передаёт сигнал со входа на выход, как бы "просвечивает насквозь").

Меня "с детства" (со 2го курса института) научили перестать бояться и полюбить разновидность этой штуки по имени DFFE - D Flip Flop with Enable, т.е кроме входов Clk и D появляется ещё один, CE (Clock Enable), который "разрешает" триггеру отработать фронт тактовой частоты. Поначалу кажется, что это совершенно тривиальная доработка, выполненная на одном логическом элементе:

Clock Enable - что может быть проще?

(и бывает, люди БОЯТСЯ ИСПОЛЬЗОВАТЬ CE, поскольку это же clock gating, а это плохо-плохо-плохо, очень рискованно!)

Хитрость в том, что этот вход разрешения должен быть СИНХРОННЫМ, т.е вообще без проблем переносить всевозможные выбросы, покуда они затухнут к моменту фронта clk:

Clock Enable - что может быть проще?


В этом вся прелесть синхронных схем: наверняка этот clock enable неким нетривиальным образом зависит от текущего состояния. Например, счётчик продолжит счёт, если ещё не досчитал до крайнего значения, при этом наш конечный автомат находится в состоянии Run, либо надо разрешить загрузить новое значение с шины данных, ежели пришёл разрешающий сигнал на ножку sload, и так далее. И в "многоэтажной" комбинаторной логике могут проскочить выбросы, когда clock enable ошибочно установится в единицу, а потом сбросится назад в ноль (или наоборот). А ещё, как только фронт пришёл, и выходы регистров начинают выдавать своё новое состояние, clock enable может уже начать меняться, и нам это не должно навредить!

И реализовать такой вход на удивление нетривиальная задача!


Повторим схему DFF из той заметки с кратким пояснением, как оно работает:
Clock Enable - что может быть проще? IMG20220329141414.jpg

Изобразим более шуструю схему DFF на том же количестве транзисторов:
Clock Enable - что может быть проще?


Тогда мы для наглядности изобразили буферные элементы, и всю сущность триггера - буферный элемент, замкнутый на самого себя, и размыкаемый временно, чтобы занести в него новое значение.

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

Пока clk=0, первый триггер принимает в себя данные, идущие со входа. Поначалу они могут быть кривыми, потом устанавливаются, и самое последнее значение, которое было, прежде чем clk переключилось в 1, там фиксируется. И так должно происходить в любом случае: заставить его хранить старое значение именно здесь, а потом за наносекунду до переключения clk вдруг опомниться "опа, у нас ce=1, давайте быстро запоминать!" - нереально. Не может быть никаких "за наносекунду", для триггера clk=1 ПРИХОДИТ НЕОЖИДАННО, он внутри себя "не чувствует хода времени"!

Значит, чтобы при ce=0 мы могли сохранить старое значение, необходимо запретить второму триггеру переключаться в прозрачный режим, когда становится clk=1, и нужно НА ПОЛТАКТА ЗАПОМНИТЬ, что ему переключаться нельзя! Мы не можем рассчитывать, что на входе ce сохранится правильное значение, следовательно, если мы хотим пойти по этому пути, надо свой собственный триггер для ce. А это штука толстая, любой триггер, даже самый простенький RS. Там минимум два элемента И-НЕ, по КМОП технологии это 8 транзисторов. Картина маслом ПРИПЛЫЛИ.

Как ни странно, самым компактным выходом, когда нам нужен ИНДИВИДУАЛЬНЫЙ ce на один триггер, является следующий:

Clock Enable - что может быть проще?


ЕЩЁ ОДИН АНАЛОГОВЫЙ ПЕРЕКЛЮЧАТЕЛЬ. Т.е мы вообще не лезем в тактовые цепи (раз они такие злые), а попросту решаем, что подать на вход триггера. То ли новые данные с входа D, то ли свой же собственный выход, чтобы сохранить старое значение.

На всё про всё - лишних 6 транзисторов. Два из них - для "размыкающего" ключа, два - для "замыкающего", плюс инвертор, чтобы они работали в противофазе (и чтобы подать правильное напряжение на затвор p-канальных транзисторов в ключе). Причём, если у нас один сигнал ce питает сразу много триггеров, инвертор можно поставить один общий. Для контекста: тривиальный логический элемент И, с которого мы начали, потребовал бы те же 6 транзисторов, 4 на И-НЕ и инвертор на выходе. Только он бы ещё не заработал, как нам надо, а здесь всё чётко. UPD: если так подумать, инвертор дополнительно не нужен, там один уже и так есть, так что 4 транзистора. Но это схоластика, всяко схема не рабочая.

И действительно, ровно так рисуют принципиальную схему регистров с clock enable в даташитах, хотя и с заметкой "чисто в качестве иллюстрации, не используйте эту схему для оценки задержек!" Например, вот:
Clock Enable - что может быть проще?


Не знаю, почему, но вместо "аналогового переключателя" рисуют мультиплексор по классической схеме. Видимо, принципиальная схема "унаследована" с ТТЛ микросхем. Если было 74, а стало 74AC (advanced CMOS) - зачем логическую диаграмму менять!

Впрочем, встретил я и такую схему:
Clock Enable - что может быть проще?


Тут, раз уж clock enable один на 9 триггеров, можно не пихать 9 переключателей, а поставить один-единственный триггер, который запомнит, чему же clock enable равнялся при фронте clk.

Меня поначалу очень сбила с толку буква n перед всеми названиями. Я привык, что это значит negative и используется, когда у нас нет возможности нарисовать черту над именем, например, где-нибудь в verilog / VHDL, хотя оттуда оно разбрелось уже очень широко.

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

В схеме явная ошибка: у 8 триггеров тактовая частота нарисована с кружочком инверсии, но у последнего - без него.

Элемент И, у которого инвертированы ВХОДЫ, мне тоже как-то не близок. Так что перерисую по нашим ГОСТам (хотя ГОСТ не предполагает использование тетради в клеточку и рисование "от руки"):
Clock Enable - что может быть проще?


А вход я обзову всё-таки nCE, т.е с обратным знаком. Так вот, если он равен единице, значит, триггер должен хранить своё старое значение. И действительно, единица на одном из входов верхнего ИЛИ-НЕ означает заведомый ноль на его выходе, поэтому gCLK (gated CLK) будет сидеть в нуле. По сути, nCE подключён к входу R (Reset, сброс) RS-триггера.

clk подключён, соответственно, к входу S.

Обычно говорят, что подавать активные сигналы одновременно на входы S и R запрещено, но здесь это будет происходить сплошь и рядом. Поскольку мы используем выход верхнего элемента ИЛИ-НЕ, у триггера вход R получается более приоритетным, т.е когда одновременно R=S=1, на выходе получим 0 (R победит). Если они теперь одновременно сбросятся в ноль, результат окажется неопределённым - как фишка ляжет.

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

Пока clk=0, эти переключения, как минимум, не пройдут на выход за счёт элемента И. Если хоть на одно короткое мгновение nCE переключится в 1 (т.е запрет защёлкивания новых данных в наши триггеры для данных), этого хватит, чтобы RS-триггер переключился в 0. Это уже подозрительно: выходит, что nCE должен установиться в правильное значение уже к моменту clk=0, т.е на полтакта раньше! Иначе случайный сбой нарушит нашу логику.

Но и дальше всё странно. Допустим, на всём протяжении clk=0 у нас было nCE = 0 (защёлкивание данных разрешено), поэтому как RS-триггер был установлен в единицу за счёт clk=1, так пока и хранит это состояние. Вот прошёл фронт clk, т.е снова установилось clk=1, и они переданы на выход, в gCLK. Но если мы сейчас установим nCE=1, то это БЕСПРЕПЯТСТВЕННО пройдёт в gCLK внезапным переключением в ноль! А возврат в nCE=0 - переключением в единицу!

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


До сих пор для меня открыт вопрос - может ли превращение clk в троичный сигнал как-то упростить всю эту машинерию? И если да, то как вообще должен выглядеть этот сигнал - "пила" или "треугольник"?

View Poll: Clock Enable - это просто (том 1)...

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

Архив записей в блогах:
Украинский политолог раскрывает ватникам глаза на мир: ...
Сантехники - люди с грубой моторикой, живущие в позапрошлом веке. Ну елки-палки. Пакля. ПАКЛЯ!!! Ну окей, ФУМ-лента. Но почему в 21 веке до сих пор нет простого жидкого герметика, которым намазал резьбу, вкрутил, подождал, и оно герметично? Какая, бляха-муха, пакля??? ПС. К аргументу ...
Оппозиция не собирается выполнять принятый Верховной радой Украины закон об амнистии и освобождать захваченные административные здания, заявил лидер ...
Вот есть противников сексуальных связей с представителем своего пола очень много. Их можно понять, это природой либо заложено либо нет. Но я на 99% уверен, что если завязать человеку глаза, он не узнает пол партнёра, который его ласкает. Да, конечно по прикосновениям можно узнать (размер ...
Октябрь в этом году удался,грех жаловаться. Берёза летом своей огромной кроной надёжно укрывала от жары окно и стену квартиры.Сейчас уже,конечно,сильно поредела:) Васька настоящий сибарит в отличие от Дульсинеи-никогда на полу не заснёт. Васька спрятал в моём тапке свою мышь,а ...