Визуальные соответствия между написанным на Verilog коде и синтезируемой в аппаратуре логикой
Просто триггер (flip-flop).
Это просто регистр или триггер - он запоминает входные данные со входа d и подает их на выход q. Запоминание происходит в момент, когда сигнал тактовой частоты clk переходит из нуля в единицу (то есть в момент фронта сигнала clk). На языке описания аппаратуры Verilog это выглядит вот так:
reg q;
always @(posedge clk)
q <= d;
Обратите внимание, на временных диаграммах значение на выходе меняется только в момент фронта тактовой частоты:
Триггер чувствительный к отрицательному фронту сигнала тактовой частоты.
Триггер / регистр может быть активным не только по фронту (posedge), но и по спаду сигнала тактовой частоты - на языке Verilog это поведение описывается словом negedge. В схемотехническом описании у регистра появляется небольшой кружочек на сигнале clk символизирующий инвертор.
reg q;
always @(negedge clk)
q <= d;
Теперь сигнал на выходе меняется только по спаду тактовой частоты:
Триггер с асинхронным сбросом.
Ассинхронный, значит не связанный с тактовой частотой. Ассинхронные сброс или установка применяются в основном только для инициализации триггеров / регистров схемы в исходное состояние перед началом работы:
reg q;
always @(posedge clk or posedge reset)
if(reset)
q <= 1'b0;
else
q <= d;
Сигнал асинхронного сброса (или установки) имеет высший приоритет:
Триггер с синхронным сбросом
На первый взляд, вот этот код на Verilog ничем не отличается от кода регистра с ассинхронным сбросом, который мы рассмотрели чуть выше. Тем не менее, отличие кардинальное. В списке чувствительности always теперь нет "posedge reset".
reg q;
always @(posedge clk)
if(reset)
q <= 1'b0;
else
q <= d;
Результат реализации в железе тоже теперь совершенно иной: на входе появился мультиплексор выбирающий из входного сигнала d или значения "ноль" в зависимости от входного сигнала reset.
Регистр с синхронным сбросом можно представить себе как регистр с мультиплексором на входе.
Триггер со входом разрешения записи
Запись в регистр происходит только в те фронты сигнала тактовой частоты, во время которых сигнал enable установлен. На Verilog это можно написать вот так:
reg q;
always @(posedge clk)
if(enable)
q <= d;
Вход разрешения записи "в железе" может быть реализован разными способами. Например, сигнал тактовой частоты может подаваться через гейт, вот так: real_clk = clk & enable. Вторая реализация может быть, например в виде входного мультиплексора, который выбирает для записи либо новое значение d, либо предыдущее, уже запомненное q.
Регистр со входом разрешения записи и асинхронным сбросом
Опишем его на Verilog вот так:
always @(posedge clk or posedge reset)
if(reset)
q <= 1'b0;
else
if(enable)
q <= d;
Компилятор / синтезатор может по разному реализовать такой регистр, но поведение его в обоих случаях одинаково:
Триггер с разрешением записи с синхронной установкой и асинхронным сбросом.
Вот такое довольно мудреное описание на языке Verilog в аппаратуре может вылиться в простой регистр плюс мультиплексор.
reg q;
always @(posedge clk or posedge reset)
if(reset)
q <= 1'b0;
else
if(enable)
begin
if(set)
q <= 1'b1;
else
q <= d;
end
Такая схема запоминает входное значение, либо единицу по фронту тактовой частоты clk, но только если сигнал разрешения записи enable установлен.
Триггер с разрешением записи с синхронной установкой и асинхронным сбросом, но сигнал установки имеет безусловный приоритет.
Вот такой код на Verilog дает приоритет сигналу set перед сигналом enable:
reg q;
always @(posedge clk or posedge reset)
if(reset)
q <= 1'b0;
else
if(set)
q <= 1'b1;
else
if(enable)
q <= d;
В данном примере по сигналу set и фронту тактовой частоты clk регистр всегда будет устанавливаться в единицу, не зависимо от сигнала enable. Ну а уж если set не установлен, то новое значение сигнала d будет записано или нет в зависимости от enable.
Подробнее...