Этот раздел описывает создание синхронизированного триггера на языке VHDL, и то, как определить разрешающий сигнал в процессе. Некоторые технологические устройства для этого имеют специальный разъем на их базовых конструктивных блоках. Инструментальные средства синтеза распознают функцию доступа в VHDL описании и генерируют триггер с разрешающим сигналом, как например в следующем кодовом фрагменте:
signal DATA,Q_OUT,ENABLE,CLK: std_logic;
...
process (CLK)
begin
if (CLK'event and CLK='1') then
if (ENABLE='1') then
Q_OUT <= DATA;
end if ;
end if ;
end process ;
В инструкциях потока данных, синхронизация доступа может быть создана при помощи блока GUARDED и условного сигнала назначения.
B4: block (CLK'event and CLK='1')
begin
Q_OUT <= guarded DATA when ENABLE='1' else Q_OUT;
end block ;
Инструкции ожидания.
Другой способ сгенерировать триггер - использовать задержку до инструкции. Если задержка стоит перед оператором, то она может использоваться в процессе и синтезировать триггер, если это первая инструкция в процессе. Следующий кодовый фрагмент описывает триггер запускаемый между сигналами input_foo и output_foo:
signal input_foo, output_foo, ck : bit ;
...
process
begin
wait until ck'event and ck='1' ;
output_foo <= input_foo ;
end process ;
В этом процессе нет никакого списка чувствительности. В VHDL, процесс может иметь либо список чувствительности либо инструкцию ожидания. В этом примере, процесс выполняется, если в условии задержки присутствуют изменения. Также, условие ожидания может быть упрощено, на ожидание до того момента, как clk = '1' (процесс начинается), т.е. только если измененено clk’event, и таким образом clk событие - истинно.
Переменные.
Переменные (подобно сигналам) могут также описывать триггеры. Поскольку переменная определена непосредственно в процессе и ее значение постоянно, единственное случай, когда переменная может описывать триггер это, когда переменная используется до описания синхронизированного процесса. Например, следующий пример кода описывает трех - разрядный сдвиговый регистр.
signal input_foo, output_foo, ck : bit ;
...
process (ck)
variable a, b : bit ;
begin
if (ck'event and ck='1') then
output_foo <= b ;
b := a ;
a := input_foo ;
end if ;
end process ;
В этом случае, переменные а и b используются прежде, до того как они определены. Поэтому, они передают значения от последнего исполняемого процесса, в котором присваемое значение замедленно одним тактовым циклом. Если описать переменные до того как они будут использоваться получим следующую схему:
signal input_foo, output_foo, ck : bit ;
...
process (ck)
variable a, b : bit ;
begin
if (ck'event and ck='1') then
a := input_foo ;
b := a ;
output_foo <= b ;
end if ;
end process ;
Здесь а, и b определены прежде чем используются и поэтому триггеры не создаются. Вместо этого, создается одиночный провод. В итоге остается только один триггер между input_foo и output_foo из-за назначения сигнала в синхронизированном процессе.
Неявные триггеры типа защелка.
В некоторых случаях, компилятор может генерировать последовательную логику, которую вы не можете разъединить. Как правило, это следствие условных операторов или операторов выбора, в которых возможные состояния выхода не были определены. Ниже, вы можете найти фрагмент исходного текста для мультиплексора 2:1, который кажется вполне комбинационным, но все же подразумевает логический синтезатор.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mux2 is
port (a, b, sel : in std_logic;
y : out std_logic);
end;
architecture behavior of mux2 is
begin
process (a,b,sel)
begin
if (sel='0') then
y <= a;
end if;
end process;
end behavior;
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.