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

Иерархические ссылки в Verilog: область видимости и избежание коллизий имен

Большинство языков программирования имеют характеристику области видимости (scope), определяющую видимость разделов кода для переменных и методов. Scope задает пространство имен (namespace) для предотвращения коллизий между именами объектов в одном пространстве.

Verilog определяет новую область видимости для модулей, функций, задач (tasks), именованных блоков и generate-блоков.

module tb;
  reg signal;
  // Другую переменную с тем же именем в этой же области объявить нельзя
  // reg signal; // Ошибка!
  // Но имя 'signal' можно переиспользовать внутри task — другая область
  task display();
    reg signal = 1;
    $display("signal = %0b", signal);
  endtask
endmodule

Идентификатор (например, имя сигнала) может использоваться для объявления только одного типа элемента в данной области. Нельзя иметь две переменные разного или одного типа с одним именем, или task и переменную с одним именем, или даже net и gate instance с одним именем в одной области.

У каждого идентификатора в Verilog есть уникальное иерархическое путьовое имя, где каждый инстанс модуля, task, function или именованный блок begin end / fork join задает новый уровень или область.

Пример иерархической ссылки

module tb;
  // Два инстанса разных модулей
  A uA();
  B uB();

  // Именованный блок с сигналом и выводом в 10ns
  initial begin : TB_INITIAL
    reg signal;
    #10 $display("signal=%0d", signal);
  end

  // Доступ к другим областям через иерархические ссылки
  initial begin
    TB_INITIAL.signal = 0;
    uA.display();
    uB.B_INITIAL.B_INITIAL_BLOCK1.b_signal_1 = 1;
    uB.B_INITIAL.B_INITIAL_BLOCK2.b_signal_2 = 0;
  end
endmodule
module A;
  task display();
    $display("Hello, this is A");
  endtask
endmodule

module B;
  initial begin : B_INITIAL
    #50;
    begin : B_INITIAL_BLOCK1
      reg b_signal_1;
      #10 $display("signal_1=%0d", b_signal_1);
    end
    #50;
    begin : B_INITIAL_BLOCK2
      reg b_signal_2;
      #10 $display("signal_2=%0d", b_signal_2);
    end
  end
endmodule

Simulation Log

xcelium> run
Hello, this is A
TB signal=0
signal_1=1
signal_2=0
xmsim: *W,RNQUIE: Simulation is complete.

Восходящие ссылки по имени (Upwards Name Referencing)

Модуль нижнего уровня может ссылаться на элементы модуля выше по иерархии. Например, сигнал в блоке TB_INITIAL виден из task display в A.

module A;
  task display();
    $display("Hello, this is A");
    // Восходящая ссылка, TB_INITIAL виден в этом модуле
    #5 TB_INITIAL.signal = 1;
  endtask
endmodule

Теперь TB signal равен 1 вместо 0 из-за изменения модулем A.

Simulation Log

xcelium> run
Hello, this is A
TB signal=1
signal_1=1
signal_2=0
xmsim: *W,RNQUIE: Simulation is complete.

Еще пример с множественными вложенными модулями: листовой узел напрямую обращается к членам выше по иерархии через восходящую ссылку.

module tb;
  A a();
  function display();
    $display("Hello, this is TB");
  endfunction
endmodule

module A;
  B b();
  function display();
    $display("Hello, this is A");
  endfunction
endmodule

module B;
  C c();
  function display();
    $display("Hello, this is B");
  endfunction
endmodule

module C;
  D d();
  function display();
    $display("Hello, this is C");
  endfunction
endmodule

module D;
  initial begin
    a.display(); // или A.display()
    b.display(); // или B.display()
    c.display(); // или C.display()
    a.b.c.display();
  end
endmodule

Simulation Log

xcelium> run
Hello, this is A
Hello, this is B
Hello, this is C
Hello, this is C
xmsim: *W,RNQUIE: Simulation is complete.

Когда компилятор находит b.display():

  1. Ищет в текущей области (модуль D), определено ли b. Если нет — ищет в объемлющей области, поднимаясь вверх до области модуля. Если все еще не найдено — следующий шаг.
  2. Ищет в внешней области родительского модуля, и если не найдено — продолжает подниматься по иерархии.

Verilog

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