SystemVerilogにおけるステートメントラベルまとめ
SystemVerilogの**ステートメントラベル(Statement Label)**は、プロシージャルステートメントを識別するための仕組みです。
ラベルを付けることで、スコープの明示化やdisable
文による制御、階層名での参照が可能になります。
1. 定義と基本構文
- ステートメントラベルは、非宣言ステートメントの前に指定できます。
- 構文は以下の通りです:
label_name: statement;
- ラベル付きステートメントは、
disable
文で強制終了させることができます。 - また、ラベルを付けると、暗黙的に名前付きブロックが生成されます。このブロックは階層名で参照可能です。
2. 基本的な使い方
単一ステートメントにラベルを付ける
task automatic sample_task();
int i = 0;
loop1: while (i < 10) begin
i++;
if (i == 5) disable loop1; // ラベルloop1でループを終了
end
endtask
この例では、while
文にラベルloop1
を付け、途中でdisable
文によって実行を終了できます。
3. ブロックへの適用
ステートメントラベルをbegin-endブロックまたはfork-joinブロックの前に指定することは、そのブロックに名前を付けることと同等です。
これにより、新しい階層スコープが作成されます。
この形式でラベルを使用した場合にも、ブロックの終わり(end、join、join_any、join_none)に、コロンの後に一致するブロック名を指定することが許可されま
blockA: begin
int x = 0;
x = x + 1;
end : blockA
parBlock: fork
// 並列処理のコード
join_none : parBlock
注記: begin または fork の前にラベルを付ける場合、キーワードの後にブロック名を指定することはできません。
4. foreach/for ループへの適用
foreachループにラベルを付けた場合、foreachループが生成する暗黙的なbegin-endブロック(スコープ)に名前が付けられます。
forループの場合、ループ制御変数がfor_initializationの一部として宣言されている場合(例:for (int i = 0; ...)には暗黙に生成されるbegin-endブロック(スコープ)に名前が付けられます。
これにより、ループを途中で終了する制御が可能になります。
outer_for: for (int i = 0; i < 100; i++) begin
if (i == 10) begin
disable outer_for; // ループを抜ける
end
end
forループのループ変数がループ外で宣言されている場合(例:int i; outer_for: for (i = 0; ...))、ラベルは単にループ・ステートメント自体にステートメントラベルをつけたと解釈されます。
すなわちforステートメント自体を囲む名前付きのbegin-endブロックを作成します。
5. アサーションへの適用
ラベルは、アサーションの前にも付けることができます。
ラベル付きアサーションは階層名で参照可能ですが、ラベルなしアサーションは参照できません。
module m(input logic clk, a, b);
initial begin : B1
assert (a); // ラベルなし → 参照不可
A1: assert (a) begin
$display("assertion A1 passed");
end else begin : B2
bit d = a ^ b;
$error("assertion A1 failed, d=%0b", d);
end
end
endmodule
-
A1
はアサーションステートメント全体を識別するラベル -
B2
はアサーションのアクションブロックに付けた名前付きブロック
これにより、階層名を用いて top.m.B1.A1.B2
のようにアクセスできます。
まとめ
- ステートメントラベルは ステートメントを識別し、
disable
による制御や階層参照を可能にする。 - 適用対象は 単一ステートメント・ブロック・ループ・アサーション。
- ラベルを付けることで、コードの可読性と制御性が向上する。
Discussion