Поиск…


замечания

D-Flip-Flops (DFF) и защелки - это элементы памяти. 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;

Примечание: в этом последнем примере мы также упростили тест на сброс. Плавающие, высокие импедансы, сбрасывания довольно редки, и в большинстве случаев эта упрощенная версия работает для моделирования и синтеза.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow