Неполные, если утверждения и вывод защелки в VHDL
В этой статье мы увидим, что элемент памяти может быть непреднамеренно выведен из неполного оператора «if».
В моей предыдущей статье Sequential VHDL: If и Case Statement мы рассмотрели некоторые примеры инструкции if.
В этой статье основное внимание будет уделено неполным операциям if. Мы увидим, что элемент памяти может быть непреднамеренно выведен из либо неполного оператора «if», либо неполных назначений сигналов в выражении «if». Наконец, мы рассмотрим пример приложения, в котором нам нужно иметь D-защелки в нашем дизайне.
«Если» Заявления без отделения «Другие»
«Если» утверждения без ветки «else» могут привести к нежелательному выходу защелки. Давайте посмотрим пример:
Пример 1: Рассмотрим следующий код:
1 library IEEE; 2 use IEEE. STD_LOGIC_1164. ALL; 3 entity Latch1 is 4 Port (d: in STD_LOGIC; 5 c: in STD_LOGIC; 6 q: out STD_LOGIC); 7 end Latch1; 8 architecture Behavioral of Latch1 is 9 begin 10 process(d, c) 11 begin 12 if (c='1') then 13 q <= d; 14 end if; 15 end process; 16 end Behavioral;
Этот оператор «if» является неполным, потому что он не имеет ветку «else». В соответствии с этим кодом, когда вход c высок, выход q будет равен входу d.
Что, если c равно нулю "// www.allaboutcircuits.com/textbook/digital/chpt-10/edge-triggered-latches-flip-flops/" target = "_ blank"> flip-flop (DFF), показанный в Рисунок 1 (b) прозрачен на переднем фронте clk; в противном случае выход сохраняет прежнее значение.
Использование триггеров распространено в последовательной схеме, тогда как защелки используются только изредка. Неполная инструкция «if» примера 1 является стандартным кодом для реализации защелки D. Вот почему программное обеспечение для синтеза не выдает сообщение об ошибке для вышеуказанного неполного оператора «if». Дизайнер должен включать ветку «else», чтобы избежать вывода защелки (если конечно не требуется защелка).

Рисунок 1. Защелка D на положительном уровне (a) и положительный фронт DFF (b)
Схема RTL приведенного выше кода, созданного Xilinx ISE, показана на рисунке 2. Как вы можете видеть, существуют некоторые буферы вместе с экземпляром ld. Экземпляр ld на этом рисунке представляет собой защелку (см. Стр. 275 руководства по библиотекам Xilinx для схемных проектов).

фигура 2
Пример 2. Запишите код VHDL для схемы с выходом, eq и двумя двухбитовыми входами a и b. Схема сравнивает входы; если a = b, выход, eq, равен 1.
1 library IEEE; 2 use IEEE. STD_LOGIC_1164. ALL; 3 entity comp1 is 4 Port (a: in STD_LOGIC_VECTOR(1 downto 0); 5 b: in STD_LOGIC_VECTOR(1 downto 0); 6 eq: out STD_LOGIC); 7 end comp1; 8 architecture Behavioral of comp1 is 9 begin 10 process(a, b) 11 begin 12 if (a=b) then 13 eq <= '1'; 14 end if; 15 end process; 16 end Behavioral;
Еще раз, оператор «if» не имеет ветку «else». Основываясь на обсуждении предыдущего примера, мы можем ожидать, что этот код приведет к выходу защелки. Моделирование ISE для этого кода показано на рисунке 3.

Рисунок 3
От 0 нс до 200 нс симулятор не может присвоить значение выходному экв; поэтому eq не инициализируется в течение этого интервала. От 200 нс до 300 нс два входа равны, а экв - единице. После 300 нс, хотя входы больше не равны, выходной эквалайзер остается высоким для остальной части симуляции. Это показывает эффект памяти для eq в симуляции. Схема RTL, сгенерированная ISE, показана на рисунке 4.

Рисунок 4
Мы видим, что этот код VHDL не привел к созданию правильно спроектированной схемы. Вопреки нашим ожиданиям, выводов защелки не произошло. Вместо этого выходной eq просто подключается к VCC через буфер; другими словами, выход всегда логичен.
Этот пример демонстрирует тот факт, что неинициализированное значение будет отображаться как логическое, так и низкое во время синтеза. Чтобы достичь намеченной операции, мы можем включить ветку «else» и переписать вышеупомянутый процесс как
Листинг 1
process(a, b) begin if (a=b) then eq <= '1'; else eq <= '0'; end if; end process;
Моделирование нового кода показано на рисунке 5. Как вы можете видеть, когда два входа равны, выход eq равен единице; когда они не равны, выход равен нулю.

Рисунок 5
Можно избежать вывода защелки при использовании оператора «if» без ветки «else». Помните, что без ветки «else» последнее значение en сохраняется, когда условие после ключевого слова «if» равно false. Назначая значение eq, перед оператором if, мы можем избежать непреднамеренного вывода защелки. В этом случае назначение по умолчанию перед оператором if будет указывать значение eq, когда условие «if» равно false:
Листинг 2
process(a, b) begin eq <= '0'; if (a=b) then eq <= '1'; end if; end process;
Функциональность, реализованная в листинге 2, фактически эквивалентна функциям Листинга 1.
«Если» Заявления с неполным назначением сигнала
Иногда оператор «if» имеет ветку «else», но есть сигналы, которые не получают значения при определенных условиях. В этой ситуации неназначенные сигналы сохранят свое последнее значение, и, следовательно, мы можем ожидать, что неполное распределение сигнала приведет к непреднамеренному выходу защелки, как и к отсутствию оператора else. Например, рассмотрим следующий процесс:
process(a, b, c) begin if (a=b) then ab_eq <= '1'; elsif (a=c) then ac_eq <= '1'; else not_eq <= '1'; end if; end process;
Ввод a сравнивается с b и c и, основываясь на результате этих двух сравнений, три выхода ab_eq, ac_eq и not_eq могут получить значение. Однако каждая ветвь оператора «if» указывает значение только одного из выходов. Например, когда a = b, выход ab_eq будет установлен в один, но два других выхода не получат значение.
Таким образом, приведенный выше код вызовет вывод защелки для трех выходов. Чтобы избежать вывода защелки, есть два возможных решения: мы можем либо присваивать значения всем трем выходам в каждой ветви оператора if, либо мы можем назначить выходы по умолчанию перед оператором if. Последнее решение используется в следующем сегменте кода:
process(a, b, c) Begin ab_eq <= '0'; ac_eq <= '0'; not_eq <= '0'; if (a=b) then ab_eq <= '1'; elsif (a=c) then ac_eq <= '1'; else not_eq <= '1'; end if; end process;
Теперь, когда мы знакомы с тем, чтобы избежать непреднамеренного вывода защелки, давайте посмотрим пример, где мы действительно хотим иметь элементы D-защелки в нашем дизайне. Хорошим примером приложения D-защелки является двухстрочный триггер.
Флип-флоп с двойным краем
В отличие от обычного D-триггера, который чувствителен либо к нарастающему фронту, либо к заднему фронту тактового импульса, двухгранный D-триггер становится прозрачным как на восходящем, так и на заднем фронте часов. Другими словами, триггер с двумя границами хранит данные на обоих тактовых переходах.
Вы можете придумать некоторые инновационные варианты кодирования для реализации такого триггера, но не все из этих методов будут работать. (Чтобы прочитать о некоторых распространенных ошибках в этом отношении, я бы рекомендовал прочитать раздел 7.6 «Проектирование схемы и моделирование с помощью VHDL»).
Соответствующим способом создания двухстрочного триггера является использование двух параллельных защелок в сочетании с мультиплексором. Этот метод не нужен, если вы используете FPGA, который включает в себя двухгранные триггеры как часть его внутреннего оборудования.
Схема показана на рисунке 6.

Рисунок 6
В этой конструкции верхняя защелка D представляет собой защелку позитивного уровня. Он отображает значение ввода данных непосредственно перед падающим фронтом clk. Нижняя защелка представляет собой защелку D отрицательного уровня, которая производит выборку ввода данных непосредственно перед нарастающим краем clk. Если мы применяем часы к обем защелкам и к мультиплексору, который выбирает между выходами двух защелок, мы можем назначить D на Q каждый раз, когда часы переходят. Реализация VHDL будет использовать сегменты кода, аналогичные сегментам примера 1, для генерации защелок D (см. Пример 7.6 этой книги для полного описания VHDL двукратного DFF).
Резюме
- «Если» утверждения без ветки «else» могут привести к нежелательному выходу защелки.
- Флип-флоп - это чувствительный к краю элемент памяти, а защелка чувствительна к уровню.
- Мы можем использовать назначение по умолчанию перед оператором if, чтобы избежать непреднамеренного вывода защелки, даже если ни одна ветка «else» не включена.
- Неполное назначение сигнала в выражении «if» может привести к непреднамеренному выходу защелки.
- Двусторонний D-триггер становится прозрачным как на восходящем, так и на заднем фронте часов. Если целевой FPGA имеет только однострочные триггеры, мы можем использовать две параллельные защелки вместе с мультиплексором для создания триггера с двумя краями.
Чтобы просмотреть полный список моих статей, перейдите на эту страницу.