Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Verilog

Понимание операторов assign в Verilog: непрерывное присваивание сигналов

Сигналы типа wire или подобные wire-типы требуют непрерывного присваивания значения. Например, электрический провод на макетной плате: пока к одному концу подключён аккумулятор +5В, компонент на другом конце получает нужное напряжение.

В Verilog эта концепция реализуется оператором assign, где любой wire или похожий тип может непрерывно управляться значением. Значение может быть константой или выражением из группы сигналов.

Синтаксис assign

Синтаксис начинается с ключевого слова assign, за которым следует имя сигнала (одиночный или конкатенация разных сетей). Сила драйвера (drive strength) и задержка (delay) опциональны и в основном используются для моделирования потока данных, а не для синтеза в реальное железо. Выражение справа вычисляется и присваивается сети или выражению сетей слева.

assign  = [drive_strength] [delay] <выражение сигналов или константа>

Значения задержки полезны для задания задержек гейтов и моделирования временного поведения реального железа, так как определяют, когда сеть получит вычисленное значение.

Правила

Пример #1

Сеть out непрерывно управляется выражением сигналов i1 и i2 с логическим И &.

Если провода превратить в порты и синтезировать, получится RTL-схема, показанная ниже.

Оператор непрерывного присваивания можно использовать для представления комбинационных гейтов в Verilog.

Пример #2

Модуль ниже принимает два входа и использует assign для управления выходом z с part-select и множественными конкатенациями бит. Каждый случай рассматривайте как единственный код в модуле, иначе множественные assign на один сигнал сделают выход X.

module xyz (input [3:0] x, input y, output [4:0] z);
wire [1:0] a; wire b;
// Допустим x='hC, y='h1, смотрим значение z
// Case #1: 4 бита x и 1 бит y конкатенируются в 5-битную сеть -> z='b11001 (0x19)
assign z = {x, y};
// Case #2: то же, но присваиваем только 3 бита z[3:1]. Остальные 2 бита z — high-Z -> z='bZ001Z
assign z[3:1] = {x, y};
// Case #3: бит 4 z управляется константой 1. Теперь z='b1001Z (только бит 0 high-Z)
assign z[3:1] = {x, y}; assign z[4] = 1;
// Case #4: бит 3 управляется вместо этого, но два драйвера для бита 3 с одинаковым значением 0 -> нет конфликта, z='bZ001Z
assign z[3:1] = {x, y}; assign z[3] = 0;
// Case #5: бит 3 управляется значением 1, два драйвера с разными значениями (первый даёт 0, второй 1) -> бит становится X, z='bZX01Z
assign z[3:1] = {x, y}; assign z[3] = 1;
// Case #6: Частичный выбор операндов RHS: только 2 бита из x -> z='b00001 (z[4:3] = 0)
assign z = {x[1:0], y};
// Case #7: Явно присваиваем только 3 бита z, остальные не подключены -> z='bZZ001
assign z[2:0] = {x[1:0], y};
// Case #8: Та же переменная многократно: 3{y} = {y,y,y} -> z='b00111
assign z = {3{y}};
// Case #9: LHS тоже конкатенирован: a — 2 бита, b — скаляр. RHS=11001, LHS 3 бита -> первые 3 бита с LSB RHS идут в LHS: a='b00, b='b1
assign {a, b} = {x, y};
// Case #10: Меняем порядок на LHS, RHS тот же -> a='b01, b='b0
assign {b, a} = {x, y};
endmodule

Присваивание переменным reg

Недопустимо управлять или присваивать переменным типа reg через assign. Это потому, что reg способен хранить данные и не требует непрерывного управления. reg сигналы можно управлять только в процедурных блоках initial и always.

Неявное непрерывное присваивание (Implicit Continuous Assignment)

Когда assign используется для присваивания сети — это явное присваивание. Verilog позволяет присваивание при объявлении сети — неявное присваивание.

wire [1:0] a; assign a = x & y; // Явное
wire [1:0] a = x & y;            // Неявное

Проектирование комбинационной логики

Рассмотрим цифровую схему из комбинационных гейтов и соответствующий Verilog-код.

Комбинационная логика требует непрерывного управления входами для поддержания выхода, в отличие от последовательных элементов (триггеры), где значение захватывается и хранится по фронту такта. Поэтому assign идеально подходит: выход o обновляется при любом изменении входов справа.

module combo ( input a, b, c, d, output o);
assign o = ~((a & b) | c ^ d);
endmodule

Аппаратная схема

После элаборации и синтеза получаем комбинационную схему, работающую так же, как моделирует assign.

Сигнал o становится 1, когда комбинационное выражение справа истинно. o становится 0, когда RHS ложно. Выход o равен X с 0ns до 10ns, потому что входы X в то же время.

Нажмите для слайд-шоу с примером симуляции!

Verilog

  1. Освоение оператора switch в C#: синтаксис, примеры и лучшие практики
  2. Оператор break в C#: как и когда использовать
  3. Оператор continue в C#: как эффективно пропускать итерации циклов
  4. Освоение конкатенации в Verilog: практическое руководство
  5. Понимание назначений в Verilog: типы, синтаксис и лучшие практики
  6. Блокирующие и неблокирующие назначения в Verilog: ключевые различия
  7. Мастерство функций в Verilog для эффективного RTL дизайна
  8. Понимание задач (Tasks) в Verilog: отличия от функций, синтаксис и применение
  9. Генератор тактового сигнала в Verilog: проектирование и реализация
  10. Мастерство математических функций Verilog для эффективного аппаратного дизайна