Иерархическая справочная область Verilog
Большинство языков программирования имеют характерную особенность, называемую scope. который определяет видимость определенных разделов кода для переменных и методов. Область определяет пространство имен чтобы избежать конфликтов между разными именами объектов в одном пространстве имен.
Verilog определяет новую область для модулей, функций, задач, именованных блоков и блоков генерации.
module tb;
reg signal;
// Another variable cannot be declared with
// an already existing name in the same scope
reg signal;
// However, the name 'signal' can be reused inside
// a task because it belongs to a different scope.
task display();
reg signal = 1;
$display("signal = %0b", signal);
endtask
endmodule
Идентификатор, как и имя сигнала, может использоваться для объявления только одного типа элемента в заданной области. Это означает, что две переменные с разными или одинаковыми типами данных не могут иметь одинаковое имя, или задача и переменная с одинаковыми именами, или даже экземпляр сети и шлюза с одинаковыми именами в одной и той же области.
Каждый идентификатор в Verilog имеет уникальное иерархическое имя пути, где каждый экземпляр модуля, задача, функция или названный begin end
или fork join
блок определяет новый уровень или область действия.
Пример иерархической ссылки
module tb;
// Create two instances of different modules
A uA();
B uB();
// Create a named block that declares a signal and
// prints the value at 10ns from simulation start
initial begin : TB_INITIAL
reg signal;
#10 $display("signal=%0d", signal);
end
// We'll try to access other scopes using hierarchical
// references from this initial block
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
Журнал моделирования xcelium> run Hello, this is A TB signal=0 signal_1=1 signal_2=0 xmsim: *W,RNQUIE: Simulation is complete.
Ссылка на имя вверх
Модуль более низкого уровня может ссылаться на элементы в модуле над ним в иерархии. Например, сигнал в блоке TB_INITIAL будет виден из задачи отображения в A.
module A;
task display();
$display("Hello, this is A");
// Upward referencing, TB_INITIAL is visible in this module
#5 TB_INITIAL.signal = 1;
endtask
endmodule
Обратите внимание, что сигнал TB теперь равен 1 вместо 0 из-за изменения привязки вверх, сделанного в сигнале модулем A.
Журнал моделирования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(); // or A.display()
b.display(); // or B.display()
c.display(); // or C.display()
a.b.c.display();
end
endmodule
Журнал моделирования 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(),
- Он просматривает текущую область в модуле D, чтобы убедиться, что b определено. Если он не существует, то он ищет имя в охватывающей области и перемещается вверх, пока не будет достигнута область модуля. Если имя по-прежнему не найдено, выполняется переход к следующему шагу.
- Он ищет в самой внешней области родительского модуля и, если не находит, продолжает двигаться вверх по иерархии.
Verilog