Menu
Coddy logo textTech

Блок always

Часть раздела Основы путешествия по Verilog на Coddy — урок 46 из 90.

Процедурный блок — это блок кода, в котором операторы выполняются один за другим, последовательно — как в языках программирования вроде C или Python. В Verilog есть два процедурных блока: initial (выполняется один раз) и always (выполняется непрерывно). Начнем с блока always.

Блок always выполняется непрерывно — он повторяется бесконечно с момента запуска симуляции. Он используется для описания аппаратного обеспечения, которое должно работать постоянно, такого как триггеры, счетчики и комбинационная логика.

Базовый синтаксис:

always @(sensitivity_list) begin
  // Код, который выполняется повторно
end

@(sensitivity_list) сообщает блоку, когда выполняться. Без него (и без задержки, такой как #5 внутри) блок зациклился бы бесконечно и вызвал бы зависание симуляции.

Пример блока Always: Counter

Вот пример того, как мы можем использовать блок always для создания счетчика.

module counter (
  input clk,
  output reg [3:0] count
);
  always @(posedge clk) count <= count + 1;
endmodule

Как работает этот код

ЧастьЗначение
alwaysВыполнять этот код постоянно, бесконечно
@(posedge clk)Ждать перехода тактового сигнала из 0 в 1 (нарастающий фронт)
count <= count + 1Взять текущее значение count, прибавить 1 и сохранить обратно

Блок выполняется по каждому нарастающему фронту тактового сигнала. Каждый раз count увеличивается на 1.

Список чувствительности @(posedge clk) указывает выполнять его только по фронтам тактового сигнала, а не непрерывно. Без этого цикл выполнялся бы бесконечно без задержки.

Блок always с несколькими сигналами

Вы можете перечислить конкретные сигналы:

always @(a or b) begin
  out = a & b;
end

Это выполняется, когда изменяется a или b.

challenge icon

Задание

Добавьте пропущенный блок always, чтобы этот модуль заработал.

Как это работает:

  • На каждом восходящем фронте тактового сигнала (clk) out1 переключается (меняется) с 0 на 1 или с 1 на 0
  • out2 следует за out1 (принимает то же значение, что и out1)

Что нужно сделать:

  1. Добавьте блок always @(posedge clk)
  2. Внутри него сделайте так, чтобы out1 переключался (используйте out1 = ~out1)
  3. Сделайте out2 равным out1

Попробуйте сами

module toggler (
  input clk,
  output reg out1,
  output reg out2
);

  initial begin
    out1 = 0;
    out2 = 0;
  end

  // TODO: Добавить блок always с posedge clk
  // out1 переключается каждый clock
  // out2 следует за out1

endmodule
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Основы