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
シグナル名のような識別子は、特定のスコープで 1 つのタイプの項目のみを宣言するために使用できます。これは、異なるデータ型または同じデータ型の 2 つの変数が同じ名前を持つことはできないこと、同じ名前のタスクと変数、または同じスコープ内の同じ名前を持つネットとゲート インスタンスであることさえできないことを意味します。
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
モジュール A によって信号が上方参照に変更されたため、TB 信号は 0 ではなく 1 になっていることに注意してください。
シミュレーションログ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() を見つけると、
<オール>Verilog