Menu
Coddy logo textTech

Блок always

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

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

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

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

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

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

Пример блока always: Счетчик

Вот пример того, как мы можем использовать блок 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, чтобы этот модуль заработал.

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

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

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

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

Шпаргалка

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

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

@(posedge clk) срабатывает по переднему фронту тактового сигнала; @(a or b) срабатывает при изменении любого из перечисленных сигналов.

// Счетчик: увеличивается на каждом переднем фронте тактового сигнала
always @(posedge clk) count = count + 1;

// Комбинационная логика: выполняется при изменении a или b
always @(a or b) begin
  out = a & b;
end

Примечание: выходные сигналы, управляемые блоками always, должны быть объявлены как reg.

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

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

  initial begin
    out1 = 0;
    out2 = 0;
  end

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

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

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

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