vhdl
D-Flip-Flops (DFF) и защелки
Поиск…
замечания
D-Flip-Flops (DFF) и защелки - это элементы памяти. DFF сэмплирует свой вход на одном или другом краю своих часов (не оба), в то время как защелка прозрачна на одном уровне ее включения и запоминания на другом. На следующем рисунке показана разница:
Моделирование DFF или защелок в VHDL очень просто, но есть несколько важных аспектов, которые необходимо учитывать:
Различия между моделями VHDL DFF и защелками.
Как описать края сигнала.
Как описать синхронный или асинхронный набор или сброс.
D-Flip-Flops (DFF)
Во всех примерах:
-
clk- часы, -
d- вход, -
q- выход, -
srst- активный активный синхронный сброс, -
srstn- активный низкий синхронный сброс, -
arst- активный высокий асинхронный сброс, -
arstn- активный низкий асинхронный сброс, -
sset- активный активный синхронный набор, -
ssetn- активный низкий синхронный набор, -
aset- активныйasetнабор, -
asetn- активный низкий асинхронный набор
Все сигналы имеют тип ieee.std_logic_1164.std_ulogic . Используемый синтаксис - это тот, который приводит к правильным результатам синтеза со всеми логическими синтезаторами. Пожалуйста, см. Пример обнаружения края часов для обсуждения альтернативного синтаксиса.
Восходящие фронтовые часы
process(clk)
begin
if rising_edge(clk) then
q <= d;
end if;
end process;
Падающие фронтовые часы
process(clk)
begin
if falling_edge(clk) then
q <= d;
end if;
end process;
Восходящие фронтовые часы, синхронный активный высокий сброс
process(clk)
begin
if rising_edge(clk) then
if srst = '1' then
q <= '0';
else
q <= d;
end if;
end if;
end process;
Восходящие фронтовые часы, асинхронный активный высокий сброс
process(clk, arst)
begin
if arst = '1' then
q <= '0';
elsif rising_edge(clk) then
q <= d;
end if;
end process;
Падающие фронтовые часы, асинхронный активный низкий сброс, синхронный активный высокий набор
process(clk, arstn)
begin
if arstn = '0' then
q <= '0';
elsif falling_edge(clk) then
if sset = '1' then
q <= '1';
else
q <= d;
end if;
end if;
end process;
Rising edge clock, асинхронный активный высокий сброс, асинхронный активный низкий набор
Примечание: установка имеет более высокий приоритет, чем сброс
process(clk, arst, asetn)
begin
if asetn = '0' then
q <= '1';
elsif arst = '1' then
q <= '0';
elsif rising_edge(clk) then
q <= d;
end if;
end process;
Задвижки
Во всех примерах:
-
en- сигнал разрешения, -
d- вход, -
q- выход, -
srst- активный активный синхронный сброс, -
srstn- активный низкий синхронный сброс, -
arst- активный высокий асинхронный сброс, -
arstn- активный низкий асинхронный сброс, -
sset- активный активный синхронный набор, -
ssetn- активный низкий синхронный набор, -
aset- активныйasetнабор, -
asetn- активный низкий асинхронный набор
Все сигналы имеют тип ieee.std_logic_1164.std_ulogic . Используемый синтаксис - это тот, который приводит к правильным результатам синтеза со всеми логическими синтезаторами. Пожалуйста, см. Пример обнаружения края часов для обсуждения альтернативного синтаксиса.
Активное высокое разрешение
process(en, d)
begin
if en = '1' then
q <= d;
end if;
end process;
Активное низкое разрешение
process(en, d)
begin
if en = '0' then
q <= d;
end if;
end process;
Активный высокий разрешающий, синхронный активный высокий сброс
process(en, d)
begin
if en = '1' then
if srst = '1' then
q <= '0';
else
q <= d;
end if;
end if;
end process;
Активное высокое разрешение, асинхронный активный высокий сброс
process(en, d, arst)
begin
if arst = '1' then
q <= '0';
elsif en = '1' then
q <= d;
end if;
end process;
Активное низкое разрешение, асинхронный активный низкий сброс, синхронный активный высокий набор
process(en, d, arstn)
begin
if arstn = '0' then
q <= '0';
elsif en = '0' then
if sset = '1' then
q <= '1';
else
q <= d;
end if;
end if;
end process;
Active high enable, асинхронный активный высокий сброс, асинхронный активный низкий набор
Примечание: установка имеет более высокий приоритет, чем сброс
process(en, d, arst, asetn)
begin
if asetn = '0' then
q <= '1';
elsif arst = '1' then
q <= '0';
elsif en = '1' then
q <= d;
end if;
end process;
Обнаружение краев часов
Рассказ
Whith VHDL 2008 и если тип часов bit , boolean , ieee.std_logic_1164.std_ulogic или ieee.std_logic_1164.std_logic , обнаружение краев часов может быть закодировано для нарастающего фронта
-
if rising_edge(clock) then -
if clock'event and clock = '1' then -- type bit, std_ulogic or std_logic -
if clock'event and clock then -- type boolean
и для падения
-
if falling_edge(clock) then -
if clock'event and clock = '0' then -- type bit, std_ulogic or std_logic -
if clock'event and not clock then -- type boolean
Это будет вести себя так, как ожидалось, как для моделирования, так и для синтеза.
Примечание: определение нарастающего фронта по сигналу типа
std_ulogicнемного сложнее, чем простой,if clock'event and clock = '1' then. Например, стандартная функцияrising_edgeимеет другое определение. Даже если это, вероятно, не будет иметь никакого значения для синтеза, это может сделать одно для моделирования.
Использование rising_edge и falling_edge стандартных функций настоятельно рекомендуется. В предыдущих версиях VHDL для использования этих функций может потребоваться явно объявить использование стандартных пакетов (например, ieee.numeric_bit для типа bit ) или даже определить их в пользовательском пакете.
Примечание: не используйте
rising_edgeиfalling_edgeстандартных функций для обнаружения краев без тактовых сигналов. Некоторые синтезаторы могли заключить, что сигнал - это часы. Подсказка: обнаружение края на нечасовом сигнале часто может выполняться путем выборки сигнала в сдвиговом регистре и сравнения выборочных значений на разных этапах сдвигового регистра.
Длинная история
Правильное описание обнаружения краев тактового сигнала имеет важное значение при моделировании D-Flip-Flops (DFF). Край, по определению, является переходом от одного конкретного значения к другому. Например, мы можем определить нарастающий фронт сигнала типа bit (стандартный VHDL-перечисляемый тип, который принимает два значения: '0' и '1' ) как переход от '0' к '1' . Для типа boolean мы можем определить его как переход от false к true .
Часто используются более сложные типы. ieee.std_logic_1164.std_ulogic тип ieee.std_logic_1164.std_ulogic также является перечисленным типом, как bit или boolean , но имеет 9 значений вместо 2:
| Значение | Имея в виду |
|---|---|
'U' | Uninitialized |
'X' | Принуждение неизвестно |
'0' | Принуждение к низкому уровню |
'1' | Принуждение высокого уровня |
'Z' | Высокий импеданс |
'W' | Слабый неизвестный |
'L' | Слабый низкий уровень |
'H' | Слабый высокий уровень |
'-' | Не волнует |
Определение нарастающего фронта для такого типа немного сложнее, чем для bit или boolean . Мы можем, например, решить, что это переход от '0' до '1' . Но мы также можем решить, что это переход от '0' или 'L' к '1' или 'H' .
Примечание: это второе определение, которое стандарт использует для функции
rising_edge(signal s: std_ulogic)определенной вieee.std_logic_1164.
При обсуждении различных способов обнаружения ребер важно учитывать тип сигнала. Также важно учитывать цель моделирования: только симуляция или логический синтез? Проиллюстрируем это на нескольких примерах:
Восходящий фронт DFF с битом типа
signal clock, d, q: bit;
...
P1: process(clock)
begin
if clock = '1' then
q <= d;
end if;
end process P1;
Технически, с точки зрения чистой семантики моделирования, процесс P1 моделирует DFF с нарастающим фронтом. Действительно, назначение q <= d выполняется тогда и только тогда, когда:
-
clockизменились (это то, что выражает список чувствительности) и - текущее значение
clockравно'1'.
Поскольку clock имеют тип бит, а бит типа имеет только значения '0' и '1' , это именно то, что мы определили как нарастающий фронт сигнала типа бит. Любой симулятор будет обрабатывать эту модель, как мы ожидаем.
Примечание. Для логических синтезаторов вещи немного сложнее, как мы увидим позже.
Увеличение DFF с асинхронным активным высоким сбросом и бит типа
Чтобы добавить асинхронный активный высокий сброс в наш DFF, можно попробовать что-то вроде:
signal clock, reset, d, q: bit;
...
P2_BOGUS: process(clock, reset)
begin
if reset = '1' then
q <= '0';
elsif clock = '1' then
q <= d;
end if;
end process P2_BOGUS;
Но это не работает . Условием выполнения задания q <= d должно быть: нарастающий фронт clock при reset = '0' . Но мы моделировали:
-
clockилиresetили оба изменены и -
reset = '0'и -
clock = '1'
Это не одно и то же: если reset изменяется от '1' до '0' а « clock = '1' назначение будет выполняться, пока оно не является нарастающим фронтом clock .
На самом деле, невозможно моделировать это в VHDL без помощи атрибута сигнала:
P2_OK: process(clock, reset)
begin
if reset = '1' then
q <= '0';
elsif clock = '1' and clock'event then
q <= d;
end if;
end process P2_OK;
clock'event - это event атрибута сигнала, применяемое к сигнальным clock . Он оценивается как boolean и это true тогда и только тогда, когда сигнальная clock изменилась во время фазы обновления сигнала, которая только что предшествовала текущей фазе выполнения. Благодаря этому процесс P2_OK теперь отлично моделирует то, что мы хотим в симуляции (и синтезе).
Синтез семантики
Многие логические синтезаторы идентифицируют обнаружение краев сигнала на основе синтаксических шаблонов, а не семантику модели VHDL. Другими словами, они считают, что выглядит код VHDL, а не то, какое поведение он моделирует. Один из шаблонов, которые все они распознают:
if clock = '1' and clock'event then
Итак, даже в примере процесса P1 мы должны использовать его, если хотим, чтобы наша модель была синтезирована всеми логическими синтезаторами:
signal clock, d, q: bit;
...
P1_OK: process(clock)
begin
if clock = '1' and clock'event then
q <= d;
end if;
end process P1_OK;
and clock'event часть состояния полностью and clock'event из списка чувствительности, но, как это and clock'event некоторые синтезаторы, ...
Rising edge DFF с асинхронным активным высоким сбросом и тип std_ulogic
В этом случае выражение возрастающего фронта часов и условия сброса может усложниться. Если мы сохраним определение возрастающего фронта, которое мы предложили выше, и если мы считаем, что сброс активен, если он равен '1' или 'H' , модель становится:
library ieee;
use ieee.std_logic_1164.all;
...
signal clock, reset, d, q: std_ulogic;
...
P4: process(clock, reset)
begin
if reset = '1' or reset = 'H' then
q <= '0';
elsif clock'event and
(clock'last_value = '0' or clock'last_value = 'L') and
(clock = '1' or clock = 'H') then
q <= d;
end if;
end process P4;
Примечание:
'last_value- это еще один атрибут сигнала, который возвращает значение,'last_valueперед последним изменением значения.
Вспомогательные функции
Стандарт VHDL 2008 предлагает несколько вспомогательных функций для упрощения обнаружения краев сигнала, особенно с многозначными перечисленными типами, такими как std_ulogic . std.standard пакет определяет rising_edge и falling_edge функции по типам bit и boolean и ieee.std_logic_1164 пакет определяет их по типам std_ulogic и std_logic .
Примечание: при использовании предыдущих версий VHDL для использования этих функций может потребоваться явно объявить использование стандартных пакетов (например, ieee.numeric_bit для типа бит) или даже определить их в пользовательском пакете.
Перейдем к рассмотрению предыдущих примеров и воспользуемся вспомогательными функциями:
signal clock, d, q: bit;
...
P1_OK_NEW: process(clock)
begin
if rising_edge(clock) then
q <= d;
end if;
end process P1_OK_NEW;
signal clock, d, q: bit;
...
P2_OK_NEW: process(clock, reset)
begin
if reset = '1' then
q <= '0';
elsif rising_edge(clock) then
q <= d;
end if;
end process P2_OK_NEW;
library ieee;
use ieee.std_logic_1164.all;
...
signal clock, reset, d, q: std_ulogic;
...
P4_NEW: process(clock, reset)
begin
if reset = '1' then
q <= '0';
elsif rising_edge(clock) then
q <= d;
end if;
end process P4_NEW;
Примечание: в этом последнем примере мы также упростили тест на сброс. Плавающие, высокие импедансы, сбрасывания довольно редки, и в большинстве случаев эта упрощенная версия работает для моделирования и синтеза.
