# Последовательностная логика

## Классификация цифровой логики

Цифровая логика делится на **комбинационную** и **последовательностную**.

**Комбинационная логика** (или "логика без памяти") — это цифровая логика, выходы которой зависят только от её входов. Один и тот же набор входных воздействий на эту логику всегда будет давать один и тот же результат. Комбинационную логику можно всегда представить в виде таблицы истинности (или логической функции) всех её выходов от её входов.

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

Простейшим примером комбинационной логики может быть любой логический вентиль, например исключающее ИЛИ (_рис. 1 (а)_). Эта комбинационная схема всегда будет давать `0`, если оба её входа равны, в противном случае, она выдаст `1`.

![../.pic/Introduction/Sequential%20logic/fig_01.drawio.svg](../.pic/Introduction/Sequential%20logic/fig_01.drawio.svg)

_Рисунок 1. Пример комбинационной (а), и последовательностной (б) схем._

Предположим теперь, что в качестве одного из входов исключающего ИЛИ стоит некая ячейка памяти, которая запоминает предыдущее значение, выданное этим логическим вентилем (_рис. 1 (б)_). Теперь, выходы схемы зависят не только от того, что мы подадим на вход, но и от того, что находится в данной ячейке памяти, а самое главное — теперь, подавая на вход одно и тоже воздействие, мы можем получить разные результаты.

Будем исходить из того, что изначально ячейка памяти проинициализирована нулём. Сперва подадим на вход этой схемы `0`. Поскольку оба входа равны `0`, на выход схемы подаётся `0`, и значение в ячейке памяти остаётся прежним. Затем, подадим на вход `1` — теперь на выход схемы идёт значение `1` и оно же сохраняется в ячейке памяти. После, мы снова подаём на вход `0`, однако, в отличие от первого раза, на выход схемы пойдёт `1`, т.к. входы исключающего ИЛИ не равны. Выставив на вход `1` ещё раз, мы получим на выходе `0`.

Как вы видите, результат последовательностной логики зависит от **последовательности** произведённых входных воздействий, в то время как комбинационная логика зависит от **комбинации** её текущих входных воздействий.

Последовательностная логика делится на **синхронную** и **асинхронную**.

**Синхронной логикой** называется такая логика, которая обновляет своё состояние (содержимое ячеек памяти) одновременно (**синхронно**) с фронтом тактового сигнала*. В свою очередь **асинхронная последовательностная логика** — это логика, которая может обновлять своё состояние **асинхронно** (т.е. без привязки к фронту тактового синхроимпульса). Бывает также и синхронная логика с асинхронными сигналами предустановки/сброса.

Комбинационная логика по своей природе является асинхронной, поэтому в зависимости от контекста под "асинхронной логикой" может подразумеваться как комбинационная логика, так и последовательностная логика, которая может обновлять значение не по фронту тактового синхроимпульса.

> [!Info]
> В некоторых источниках синхронной логикой могут называть и ту, что работает по уровню (а не фронту) единого источника тактового синхроимпульса [[1, стр. 164](https://reader.lanbook.com/book/241166?lms=d92e0036d4c90623ffd0a8ecc34dee72)].

## Бистабильные ячейки

**Бистабильная ячейка** — это элемент статической памяти, способный принимать одно из двух устойчивых состояний, соответствующих цифровым значениям "0" или "1".

**Статическая память** — это тип памяти, который сохраняет данные в течении неопределённого времени, пока его питание остаётся включённым, без необходимости регенерации (в отличие от **динамической памяти**, использующей для хранения конденсаторы, требующие для хранения регулярного обновления данных).

Рассмотрим простейшую ячейку статической памяти, представленную на _рис. 2_, которая способна хранить 1 бит информации.

![../.pic/Introduction/Sequential%20logic/fig_02.drawio.svg](../.pic/Introduction/Sequential%20logic/fig_02.drawio.svg)

_Рисунок 2. Простейшая ячейка статической памяти._

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

Для того, чтобы добавить в эту ячейку входы с возможностью записи данных, можно поставить перед инверторами логические элементы ИЛИ (которые совместно с инверторами образуют элементы ИЛИ-НЕ).

В результате получится **RS-триггер** — бистабильная ячейка, представленная на _рис. 3_.

## RS-триггер

![../.pic/Introduction/Sequential%20logic/fig_03.drawio.svg](../.pic/Introduction/Sequential%20logic/fig_03.drawio.svg)

_Рисунок 3. Схема и таблица истинности RS-триггера. X означает, что в этой строке результат не зависит от хранимого значения._

RS-триггер — это бистабильная ячейка, имеющая два управляющих входа: `R` (reset) и `S` (set), и два выхода: `Q` и `Q̅`. `Q̅` является инверсией `Q`. RS-триггер, построенный на логических элементах ИЛИ-НЕ, работает следующим образом:

1. Если вход `R=1`, а `S=0`, то выход верхнего элемента ИЛИ-НЕ (а значит и выход `Q`) равен `0` вне зависимости от второго его входа. Этот выход поступает вместе с входом `S` на нижний элемент ИЛИ-НЕ, который выдаёт `1` (на выход `Q̅`), поскольку оба его входа равны `0`. Эта единица подаётся на второй вход верхнего элемента ИЛИ-НЕ и теперь, даже если вход `R` станет равным `0`, `1` на втором его входе сможет воспроизвести тоже самое поведение, запирая внутри триггера стабильное состояние `Q=0`.
2. Если вход `R=0`, а `S=1`, схема работает противоположным образом: поскольку на нижний элемент подаётся `1` с входа `S`, выход `Q̅` равен `0` вне зависимости от второго входа нижнего элемента ИЛИ-НЕ. Этот ноль подаётся на второй вход верхнего элемента ИЛИ-НЕ, и поскольку оба его входа равны `0`, на выходе этого элемента (на выход `Q`) подаётся `1`, которая возвращается обратно на вход нижнего элемента ИЛИ-НЕ, запирая внутри триггера стабильное состояние `Q=1`.
3. Таким образом, если на оба входа одновременно равны `0`, RS-триггер хранит своё предыдущее значение.

Проблемой данного триггера является то, что он имеет **запрещённую** комбинацию входов. В случае RS-триггера, построенного на элементах ИЛИ-НЕ, таковой комбинацией входов является `R=1` и `S=1`. Даже с точки зрения функционального назначения, данная комбинация не имеет смысла: кому потребуется одновременно и сбрасывать RS-триггер в 0 и устанавливать его в 1? Тем не менее, вот что произойдет, если использовать эту комбинацию:

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

Для того чтобы избавиться от запрещённого состояния RS-триггера, была придумана D-защёлка (gated D-latch).

## D-защелка

D-защёлка — это бистабильная ячейка памяти, имеющая входы `D` (Data) и `E` (enable). Иногда вход enable называют clk (clock) или G (gated), что никак не сказывается на его функциональном назначении. Когда сигнал `E` равен `1`, D-защёлка "захватывает" данные с входа `D`. Когда сигнал `E` равен `0`, D-защёлка сохраняет уже захваченные данные.

D-защёлка может быть построена на базе RS-триггера, к которому добавляется логика, исключающая возможность появления запрещённого состояния (_рис. 4_).

![../.pic/Introduction/Sequential%20logic/fig_04.drawio.svg](../.pic/Introduction/Sequential%20logic/fig_04.drawio.svg)

_Рисунок 4. Схема и таблица истинности D-защёлки._

Логика работы D-защёлки заключается в следующем. Когда сигнал `E` равен `0`, логические вентили И подают на выход `0` вне зависимости от второго входа, и RS-триггер переходит в состояние хранения текущего значения. В такой ситуации говорят, что D-защёлка "закрыта", или "перешла в непрозрачное состояние". Когда сигнал `E` равен `1`, логические элементы И, добавленные перед входами RS-триггера передают на выход значение со второго их входа. При этом на второй вход этих элементов подаются противоположные сигналы: `!D` и `D`, что исключает возможность одновременного появления `1` на входах `R` и `S`. В этом случае в RS-триггер попадает значение с входа `D`, а про D-защёлку говорят, что она "открыта" (перешла в "прозрачное" состояние). Пока защёлка "прозрачна", данные со входа `D` идут напрямую на выход `Q`.

Несмотря на то, что D-защёлка устраняет главный недостаток RS-триггера, она тоже является не самой надёжной бистабильной ячейкой памяти. Дело в том, что D-защёлка пропускает на выход данные со входа `D` всё то время, пока она "прозрачна". Это значит, что она будет пропускать через себя все возможные переходные процессы сигнала `D`. Это значит, что она будет распространять переходные процессы сигналов со входа D, на которые будут реагировать последующие участки цифровой схемы. Из-за этого, через всю цифровую схему, начиная со входов, будут распространяться переходные процессы. В результате определить моменты времени, в которых на выходе схемы будет корректный результат обработки входного сигнала, станет практически невозможно. Было бы гораздо удобней, если бы могли сохранять данные одномоментно, когда на входе `D` уже находится установившееся значение, отсекая тем самым на каждом элементе памяти переходные процессы всех предыдущих участков цифровой схемы. Таким элементом памяти, является D-триггер (D flip-flop).

## D-триггер

D-триггер — это элемент статической памяти, который сохраняет данные со входа `D` **в момент перехода управляющего сигнала из нуля в единицу** (либо в момент перехода из единицы в ноль). Данный сигнал называется **сигналом синхронизации** (или **синхроимпульсом**) и обозначается как clk (clock).

На _рис. 5_ показан способ построения D-триггера из двух D-защёлок.

![../.pic/Introduction/Sequential%20logic/fig_05.drawio.svg](../.pic/Introduction/Sequential%20logic/fig_05.drawio.svg)

_Рисунок 5. Схема и таблица истинности D-триггера._

Принцип работы D-триггера, схема которого представлена на _рис. 5_ заключается в том, что управляющий сигнал `E` одной защёлки является инверсией управляющего сигнала `E` другой защёлки. Это значит, что пока одна защёлка "прозрачна" и принимает данные со входа — другая "непрозрачна" и данные не принимает. В момент, когда тактовый синхроимпульс меняет своё значение с `0` на `1`, ведущая защёлка становится "непрозрачной" для новых данных с входа `D`, и "запертые" в ней данные попадают в только что открывшуюся ведомую защёлку. Несмотря на то, что ведомая защёлка "прозрачна" всё то время, пока сигнал `clk = 1`, данные в ней остаются стабильными, поскольку выход ведущей защёлки больше не может измениться.

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

![../.pic/Introduction/Sequential%20logic/fig_06.drawio.svg](../.pic/Introduction/Sequential%20logic/fig_06.drawio.svg)

_Рисунок 6. Конфигурируемая ячейка памяти ПЛИС Xilinx XC2064 [[2, стр. 2-63](https://archive.org/details/programmablegate00xili/page/n93/mode/2up)]._

## Метастабильность

Как ранее упоминалось, при проектировании эффективных цифровых схем, необходимо оглядываться на аналоговые особенности технологии, по которой эти схемы будут реализованы. Выполним анализ простейшей бистабильной ячейки, построенной на двух инверторах. Для этого рассмотрим _рис. 7_. На _рис. 7 (а)_ показана передаточная функция U<sub>вых</sub> = T(U<sub>вх</sub>) некоторого инвертора. По оси абсцисс откладывается входное напряжение, подаваемое на инвертор, а по оси ординат — его выходное напряжение. Если подать на вход инвертора, описываемого подобной передаточной функцией напряжение, равное 0В (соответствует цифровому значению `0`), на выходе будет напряжение равное 3В (соответствует цифровому значению `1`), и наоборот: если подать на вход значение 3В, мы получим на выходе значение приблизительно равное 0В.

Поскольку в бистабильной ячейке выход одного инвертора подаётся на вход второго, оказывается удобным наложить графики передаточной функции обоих таким образом, чтобы входное напряжение одного инвертора оказалось на той же оси, где откладывается выходное напряжение другого инвертора, как представлено на _рис. 7 (б)_. Точки пересечения кривых на этом графике являются точками равновесия, в которых входные и выходные напряжения обоих инверторов являются согласованными.

![../.pic/Introduction/Sequential%20logic/fig_07.svg](../.pic/Introduction/Sequential%20logic/fig_07.svg)

_Рисунок 7. Передаточные функции для: а) одиночного КМОП-инвертора; б) пары инверторов, объединённых в бистабильную петлю [3, стр. 497]._

Как вы можете заметить, таких точек почему-то не две, а три. Две эти точки обозначены как **стабильные** и соответствуют привычным цифровым значениям 1 (для 3В) и 0 (для 0В). Третья точка равновесия обозначена как **метастабильная** и расположена примерно посередине между этими двумя значениями. И действительно, согласно графику, если подать на вход приблизительно 1.5В, на выходе будет точно такое же напряжение, которое затем будет подано на вход второго инвертора и т.д., благодаря чему петля будет находиться в подобном состоянии неопределённый промежуток времени. Подобное состояние называется **метастабильным состоянием** и присуще любой бистабильной ячейке, реализованной на электронной компонентной базе.

Традиционно, для объяснения явления метастабильности используется аналогия с шариком на холме (_рис. 8_). Предположим, шарик находится у подножия левого склона холма. Если приложить к нему достаточную силу, направленную вправо — шарик перекатится через холм, и он окажется на противоположном склоне (для удобства аналогии, на склонах холма стоят стенки, чтобы шарик останавливался всегда в одной и той же точке этого склона). Если приложить недостаточно силы — шарик поднимется немного вверх по холму, и скатится обратно, остановившись в той же точке, откуда и начал. Однако, если вы будете достаточно "удачливы" и "точны", вы можете приложить ровно столько силы, чтобы шарик поднялся на вершину холма, но не смог с неё скатиться. Этот шарик может оставаться в таком положении неопределённое количество времени, но любое малейшее возмущение (будь то лёгкое дуновение ветерка, вызванное взмахом крыла пролетевшей рядом бабочки, или далёкое землетрясение, можете придумать свою экстравагантную причину) может заставить шарик скатиться в любую сторону.

![../.pic/Introduction/Sequential%20logic/fig_08.svg](../.pic/Introduction/Sequential%20logic/fig_08.svg)

_Рисунок 8. Механическая аналогия явлению метастабильности [3, стр. 498]._

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

Если же возмущение произойдёт, пока бистабильная ячейка была в стабильном состоянии — её состояние не изменится. Предположим, что бистабильная ячейка хранит значение `1`, т.е. на вход первого инвертора подаётся значение 0В, и пришло возмущение, отклонившее это напряжение до 1В (а для подобной цифровой схемы это очень экстремальное отклонение, за пределами допустимых режимов работы). Проведём вертикальную линию до точки пересечения с черной кривой — это значение на выходе первого инвертора, и входа второго инвертора. Из этой точки, проведём горизонтальную линию до пересечения с синей кривой — это значение на выходе второго инвертора и входе первого. В общем-то, уже на этом этапе, на вход первого инвертора снова подаётся околонулевое напряжение. Именно поэтому крайние две точки пересечения называются **стабильными** — пока на схему подаётся питание, ячейка будет находиться в этом состоянии бесконечно долго до тех пор, пока не произойдёт существенного воздействия, чтобы она могла изменить это состояние.

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

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

Любые бистабильные ячейки имеют специальные временны́е параметры (ограничения), несоблюдение которых может привести к появлению метастабильности. В рамках этого курса, вы будете работать в основном с бистабильными ячейками, представленными в виде D-триггеров. Для D-триггеров таковыми временными параметрами являются:

- T<sub>setup</sub> (**setup time**) — **время предустановки**. Это интервал времени, в течение которого сигнал на входе `D` должен оставаться неизменным перед наступлением фронта тактового сигнала.
- T<sub>hold</sub> (**hold time**) — **время удержания**. Это интервал времени, в течение которого сигнал на входе `D` должен оставаться неизменным после наступления фронта тактового сигнала.

Эти два параметра образуют временное окно вокруг фронта тактового сигнала, в течение которого входной сигнал должен оставаться стабильным. Несоблюдение данных требований приводит к неопределённому поведению триггера (см. _рис. 9_). В простейшем случае он сохранит либо "старое", либо "новое" значение, пришедшее на вход данных D в непосредственной близости от фронта клока, но какое именно — неизвестно. Однако иногда "звёзды сойдутся", и триггер окажется в метастабильном состоянии. Вероятность этого крайне мала (о таком событии можно сказать, что оно "одно на миллиард"), однако не стоит относиться к нему с пренебрежением. Если схема работает на частоте в 1ГГц, триггер будет обновлять своё состояние миллиард раз в секунду, а сама схема может содержать миллионы триггеров. В таком контексте, фраза "одно на миллиард" означает не "ничего страшного, скорее при моей жизни этого не произойдёт", а "чёрт, кажется, что поэтому у меня ничего не работает".

![../.pic/Introduction/Sequential%20logic/fig_09.drawio.svg](../.pic/Introduction/Sequential%20logic/fig_09.drawio.svg)

_Рисунок 9. Пример нарушения временны́х параметров D-триггера [[4](https://habr.com/ru/articles/254869/)]._

На _рис. 9_ показано три различных исхода нарушения временных ограничений:

1. Выход триггера Q<sub>1</sub> принял новое значение сигнала D, которое было установлено во временном промежутке T<sub>setup</sub>.
2. Выход триггера Q<sub>2</sub> принял старое значение сигнала D, которое было установлено на входе до начала T<sub>setup</sub>. На следующем положительном фронте clk на входе D находится уже установившееся значение, которое без проблем записывается в триггер.
3. Перемена в уровне во время T<sub>setup</sub> привело к тому, что на триггер было подано напряжение, равное половине уровня логической единицы, и тот оказался в метастабильном состоянии. Спустя некоторое время, триггер оказался в одном из стабильных состояний, но в каком — никто заранее предсказать не может (заштрихованная область, где триггер принял значение либо 0, либо 1). На следующем положительном фронте clk на входе D находится уже установившееся значение, которое без проблем записывается в триггер.

Нарушение по T<sub>setup</sub> обычно происходит, когда схема работает на частоте, не подходящей для имеющегося у схемы критического пути. Критический путь — это комбинационная часть цифровой схемы с наибольшей задержкой распространения сигнала. Время прохождения сигнала по этому пути характеризует минимально возможный период тактового сигнала и, соответственно, максимальную тактовую частоту работы всей схемы.

Если подать на схему частоту, превышающую ограничение, определяемое критическим путём, сигнал может не принять установившееся значение на конце критического пути и, если на этом конце находится вход триггера — будут нарушено его ограничение по времени предустановки T<sub>setup</sub>.

Нарушение по T<sub>hold</sub> происходит, когда у схемы есть пути с задержкой распространения сигнала до элементов последовательностной логики, которая меньше минимально допустимой. Данные пути напрямую не влияют на значение максимальной частоты, но требуют добавления элементов задержки на кратчайшие пути. Такие пути, как правило, являются значительной проблемой при проектировании интегральных схем специального назначения (application-specific integrated circuit, **ASIC**).

Допустим в схеме есть два регистра А и Б, задержка распространения сигнала между которыми меньше допустимой. В этом случае, в момент фронта синхроимпульса с выхода регистра А может начать распространяться изменение в уровне сигнала. Это изменение достигнет входа регистра Б в этом же такте, пока у того не завершилось время удержания T<sub>hold</sub>.

Для того чтобы определить, способна ли проектируемая схема работать на целевой частоте, выполняется **статический временной анализ** (**static timing analysis**, **STA**). В процессе STA, САПР рассчитывает задержки всех временных путей схемы и определяет критический путь. Итогом статического временного анализа является оценка запаса по времени (или времени простоя, англ.: slack) для каждого временного пути, когда схема работает на заданной частоте. Если slack положительный — это значит, что задержка критического пути схемы меньше предельно допустимой, и возможно увеличение частоты схемы (например, при небольшом снижении напряжения питания) в пределах данной величины. Если slack отрицательный — это значит, что задержка по критическому пути уже превысила допустимую, и для корректной работы схемы необходимо либо изменить критический путь таким образом, чтобы сократилась его задержка распространения сигнала, либо уменьшить тактовую частоту.

К сожалению, соблюсти временны́е ограничения триггеров не всегда возможно, поскольку в некоторых случаях, вход данных может по своей природе быть асинхронен (т.е. никаким образом не зависеть от входного тактового сигнала). К примеру, данные на вход триггера подаются со входа цифровой схемы, который подключён к кнопке, нажатие на которую никак не привязано к тактовому синхроимпульсу. В других случаях, необходимо передать данные, синхронизированные с одним тактовым сигналом, в область схемы, работающей от другого тактового сигнала. Подобная ситуация называется **пересечением тактовых доменов**, или **clock domain crossing** (**CDC**). В зависимости от конкретного сценария, существуют различные схемы синхронизации, самой простой из которых является установка дополнительного триггера там, где прогнозируется возникновение метастабильного состояния (рис. 10). В высокой долей вероятности в течении 1-2 тактов на выходе синхронизирующего триггера окажется стабильное состояние, которое подавалось на вход Din. Неопределённость в количестве тактов появляется из-за того, что мы не знаем, в какую сторону "свалится" состояние первого регистра в цепи.

![../.pic/Introduction/Sequential%20logic/fig_10.drawio.svg](../.pic/Introduction/Sequential%20logic/fig_10.drawio.svg)

_Рисунок 10. Схема и временная диаграмма простейшего синхронизатора._

## Итоги главы

1. Цифровая логика делится на **комбинационную** и **последовательностную**.
   1. **Комбинационной** называют логику без памяти, выходы которой зависят только от её входов.
   2. **последовательностной** называют логику с памятью, выходы которой зависят не только от её входов, но и от её внутреннего состояния.
2. Кроме того, цифровые схемы делят на **синхронные** и **асинхронные**.
   1. **Синхронными** называют последовательностные схемы, состояние которых меняется синхронно фронту тактового сигнала.
   2. **Асинхронными** называют как комбинационные схемы, так и последовательностные схемы, изменение состояния которых может происходить без привязки к фронту тактового сигнала.
   3. Существуют синхронные схемы с асинхронными сигналами предустановки/сброса. В большинстве случаев, они рассматриваются как обычные синхронные схемы, но их асинхронная логика предустановки/сброса, должна учитываться при расчёте **критического пути**.
3. **Критический путь** — это часть цифровой схемы с наибольшей задержкой распространения сигнала, на пути которой не встречаются элементы синхронной логики.
4. **Статическая память** — это тип памяти, который сохраняет данные в течение неопределённого времени, пока его питание остаётся включённым, без необходимости регенерации.
5. **Динамическая память** — это тип памяти, использующий для хранения конденсаторы, что приводит к необходимости в регулярном обновлении содержимого памяти для того, чтобы не утратить данные.
6. Основой статической памяти является **бистабильная ячейка**.
7. **Бистабильная ячейка** — элемент, способный сохранять одно из двух устойчивых состояний, соответствующих цифровым значениям «0» или «1».
8. Простейшей бистабильной ячейкой является петля из двух инверторов. Недостатком данной реализации является отсутствие возможности подать данные в эту ячейку извне. Этот недостаток решается преобразованием цепи в **RS-триггер**.
9. **RS-триггер** — это бистабильная ячейка, имеющая два входа: сброс (reset, R) и установка (set, S). Данная ячейка может быть построена на паре логических вентилей ИЛИ-НЕ или И-НЕ. Недостатком данной бистабильной ячейки является наличие запрещённой комбинации входных сигналов, которая может привести к непредсказуемому поведению. Данный недостаток может быть разрешён путём добавления в схему дополнительной логики, из которой получается **D-защёлка**.
10. **D-защёлка** — это бистабильная ячейка, имеющая два входа: сигнал разрешения записи (`E` / `clk`), и сигнал входных данных (D). Пока сигнал `E` активен, данные со входа `D` сохраняются в D-защёлку и идут на её выход (в таких случаях говорят, что защёлка "прозрачна"). Несмотря на то, что D-защёлка разрешает проблему запрещённого состояния RS-триггера, всё то время, пока она "прозрачна", она пропускает через себя все переходные процессы входных сигналов.
11. **D-триггер** — это бистабильная ячейка, которая подобно D-защёлке имеет входы `clk` и `D`, но который сохраняет данные только в момент одного из фронтов тактового синхроимпульса (положительного или отрицательного фронта). Как и любые бистабильные ячейки, D-триггер подвержен явлению **метастабильности**. Метастабильность в D-триггере может возникнуть, если данные на входе `D` меняются во временном окне, расположенном в окрестностях фронта тактового синхроимпульса, определяемом следующими двумя параметрами:
    1. T<sub>setup</sub> (**setup time**) — **время предустановки**. Это интервал, в течение которого сигнал на входе должен оставаться неизменным перед наступлением фронта тактового сигнала.
    2. T<sub>hold</sub> (**hold time**) — **время удержания**. Это интервал, в течение которого сигнал на входе должен оставаться стабильным после наступления фронта тактового сигнала.
12. **Метастабильное состояние** — это состояние бистабильной ячейки, при котором та не находится ни в одном из стабильных цифровых состояниях `0`/`1`, находясь при этом примерно посередине между ними. Через неопределённый промежуток времени (длину которого можно оценить с точки зрения вероятностей) бистабильная ячейка может выйти из этого состояния, приняв любое из значений `0`/`1`.
13. В большинстве случаев метастабильность является нежелательным явлением в цифровой схеме. Причиной такого явления может стать работа схемы на частоте, не подходящей для имеющегося у данной схемы критического пути. Для того, чтобы узнать, сможет ли схема работать на заданной частоте, проводится **статический временной анализ** (**static timing analysis**, **STA**).
14. Метастабильность может возникнуть и в случае, если сигнал данных по своей природе является асинхронным тактовому сигналу бистабильной ячейки: он может передаваться по событиям из внешнего мира, или с выхода бистабильных ячеек, работающих от других тактовых синхроимпульсов (подобная ситуация называется **пересечением тактовых доменов**, **clock domain crossing**, **CDC**).

## Список источников

1. [Д.М. Харрис, С.Л. Харрис / Цифровая схемотехника и архитектура компьютера: RISC-V / пер. с англ. В. С. Яценков, А. Ю. Романов; под. ред. А. Ю. Романова  / М.: ДМК Пресс, 2021](https://e.lanbook.com/book/241166);
2. Xilinx / [The Programmable Gate Array Data Book](https://archive.org/details/programmablegate00xili);
3. J. Wakerly, Digital Design: Principles and Practices (5th Edition). Pearson, 2017;
4. [Метастабильность триггера и межтактовая синхронизация](https://habr.com/ru/articles/254869/).
