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

Понимание назначений в Verilog: типы, синтаксис и лучшие практики

Размещение значений на сигналах (nets) и переменных называется назначениями (assignments). Существует три основных типа:

Допустимые значения левой части (LHS)

Назначение состоит из двух частей: правой части (RHS) и левой части (LHS), разделенных символом равенства (=) или неблокирующего назначения (<=).

Тип назначения Левая часть (LHS)
Процедурное
  • Переменные (векторные/скалярные)
  • Выбор бита или части вектора reg, integer или time
  • Слово памяти
  • Конкатенация любого из вышеперечисленного
Непрерывное
  • Сигналы net (векторные/скалярные)
  • Выбор бита или части вектора net
  • Конкатенация выборов битов и частей
Процедурное непрерывное
  • Сигнал net или переменная (векторные/скалярные)
  • Выбор бита или части вектора net

Правая часть (RHS) может содержать любое выражение, вычисляемое в итоговое значение, а левая часть (LHS) указывает сигнал или переменную, которой присваивается это значение.

module tb;
  reg clk;
  wire a, b, c, d, e, f;
  reg z, y;
  
  // clk в LHS, инверсия clk в RHS
  always #10 clk = ~clk;
  
  // y в LHS, константа 1 в RHS
  assign y = 1;
  
  // f в LHS, выражение a,b,d,e в RHS
  assign f = (a | b) ^ (d & e);
  
  always @ (posedge clk) begin
    // z в LHS, выражение a,b,c,d в RHS
    z <= a + b + c + d;
  end
  
  initial begin
    // Переменные слева — LHS, 0 — RHS
    a <= 0; b <= 0; c <= 0;
    d <= 0; e <= 0; clk <= 0;
  end
endmodule

Процедурное назначение

Процедурные назначения выполняются внутри процедур (always, initial, task, function) и используются для присваивания значений переменным. Переменная сохраняет значение до следующего назначения той же переменной.

Значение помещается в переменную в момент выполнения оператора во время симуляции. Порядок выполнения можно управлять с помощью операторов управления потоком: if-else-if, case и циклов.

reg [7:0] data;
integer count;
real period;

initial begin
  data = 8'h3e;
  period = 4.23;
  count = 0;
end

always @ (posedge clk)
  count++;

Назначение при объявлении переменной

Начальное значение можно задать при объявлении переменной. Назначение не имеет длительности и удерживает значение до следующего назначения той же переменной. Обратите внимание: назначение при объявлении массива не допускается.

module my_block;
  reg [31:0] data = 32'hdead_cafe;
  initial begin
    #20 data = 32'h1234_5678;
    // data будет dead_cafe с 0 до 20
    // В момент 20 получит 12345678
  end
endmodule
reg [3:0] a = 4'b4; 
// эквивалентно
reg [3:0] a;
initial a = 4'b4;

Если переменная инициализируется при объявлении и в initial блоке в момент 0, порядок вычисления не гарантирован — результат может быть либо 8'h05, либо 8'hee.

module my_block;
  reg [7:0] addr = 8'h05;
  initial addr = 8'hee;
endmodule
reg [3:0] array [3:0] = 0; // недопустимо
integer i = 0, j;            // объявляет i,j; i = 0
real r2 = 4.5, r3 = 8;       // r2=4.5, r3=8
time startTime = 40;         // time переменная со значением 40

Процедурные блоки и назначения рассматриваются подробнее в следующем разделе.

Непрерывное назначение

Нажмите здесь для пошагового примера симуляции!

Используется для присваивания значений скалярным и векторным сигналам (nets) и срабатывает при любом изменении RHS. Обеспечивает моделирование комбинационной логики без явного описания связей гейтов и упрощает управление сигналами логическими выражениями.

// Пример модели AND гейта
wire a, b, c;
assign a = b & c;

При изменении b или c выражение RHS пересчитывается, и a обновляется.

Назначение при объявлении net

Позволяет разместить непрерывное назначение в том же операторе, что и объявление net. Поскольку net можно объявить только один раз, возможно только одно такое назначение.

wire penable = 1;

Процедурное непрерывное назначение

Это процедурные операторы, позволяющие непрерывно назначать выражения на сигналы или переменные. Существует два типа:

assign / deassign

Переопределяет все процедурные назначения переменной и отключается с помощью deassign для того же сигнала. Значение переменной остается неизменным до нового назначения через процедурное или процедурное непрерывное назначение. LHS в assign не может быть выбором бита, части или ссылкой на массив, но может быть переменной или конкатенацией переменных.

reg q;
initial begin
  assign q = 0;
  #10 deassign q;
end

force / release

Аналогичны assign - deassign, но применимы и к nets, и к переменным. LHS может быть выбором бита net, частью net, переменной или net, но не ссылкой на массив и не выбором бита/части переменной. force переопределяет все остальные назначения до release.

reg o, a, b;
initial begin
  force o = a & b;
  ...
  release o;
end

Verilog

  1. Освоение Verilog: полное руководство по проектированию цифровых схем
  2. Освоение конкатенации в Verilog: практическое руководство
  3. Мастерство функций в Verilog для эффективного RTL дизайна
  4. Понимание задач (Tasks) в Verilog: отличия от функций, синтаксис и применение
  5. Генератор тактового сигнала в Verilog: проектирование и реализация
  6. Мастерство математических функций Verilog для эффективного аппаратного дизайна
  7. Мастерство $timeformat в Verilog: точность и контроль отображения времени
  8. Понимание и печать timescale в Verilog в любой области видимости
  9. Работа с файлами в Verilog: открытие, чтение, запись и закрытие
  10. Verilog для начинающих: пример Hello World