Визуальные соответствия между написанным на 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.


Уточняю, как "автор простейших одноразовых проектов". Дело хозяйское, но для серьёзной работы такая метода совершенно непригодна (что, к счастью, прекрасно знают разработчики макроячеек ПЛИС).
И только такой подход, гарантирующий появление данных на выходе макроячеек без задержек, позволяет получать предсказуемые результаты по групповым задержкам в схеме. Плюс, разумеется, требуются специальные меры по распределению тактовых сигналов по всем макроячейкам на кристалле ПЛИС.
Гарантирую я сам себе, как автор проекта
А в части задержки - гарантирует утилита TimeQuest, которой я, к несчастью, не очень умею пользоваться
Ключевое слово ЕСЛИ. Кто гарантирует, что сигнал enable не пришёл с "тупого" блока логики? И кто гарантирует, что задержка, вносимая элементом И не приведёт к ошибкам в работе логики, использующей выходной сигнал триггера?
Именно поэтому в макроячейках ПЛИС к тактовым сигналам триггеров ничего лишнего не добавляют!
Конфликта не возникнет, если у нас enable тоже может измениться только по фронту clk.
Но вообще данная реализация относится к bad coding practice, и квартус выдаст предупреждение о наличии gated clock.
Нельзя так делать, потому что это приведёт к ошибочному срабатыванию из-за гонок фронтов.
1) фронт clk при L на enable
триггер не срабатывает, что правильно
2) с небольшой задержкой H на enable
и вот тут триггер переключается, хотя не должен!
не очень понятен вопрос, q - ведь всего лишь имя регистра.