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
标识符,如信号名称,可用于在给定范围内仅声明一种类型的项目。这意味着两个不同或相同数据类型的变量不能同名,也不能同名任务和同名变量,甚至不能同作用域内同名的net和gate实例。
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