変数の分類

変数は代入コンテキストによって分類され、これによりストレージと代入セマンティクスが決定されます。

FF変数(レジスタ)

モジュールレベルの varalways_ff ブロック内で代入されると、フリップフロップ(FF)変数になります。FF変数は二重バッファモデルを使用します:すべてのブロックから読み取れるcurrent値と、ノンブロッキング代入により書き込まれるnext値です。next値はFFコミットフェーズの後にのみcurrent値になります(シミュレーションサイクルを参照)。

組み合わせ変数

モジュールレベルの varalways_comb ブロック内または assign 宣言を通じて代入されると、組み合わせ変数になります。組み合わせ変数への書き込みは即座に反映され(ブロッキング代入セマンティクス)、評価順序における後続の読み取りから参照可能です。

モジュールレベルの let 宣言は var + assign の省略形であるため、同様に組み合わせ変数を生成します。

定数

const 宣言はコンパイル時定数を定義します。定数はコンパイル時に評価され、不変であり、シミュレーションサイクルには参加しません。

ローカル束縛

always_ff または always_comb ブロック内の let 宣言はローカル束縛を作成します。ローカル束縛は always_ff 内であっても常にブロッキング代入セマンティクスを使用します。フリップフロップにマップされることはなく、囲むブロックの外からは参照できません。

module ModuleA (
    i_clk: input clock,
    i_rst: input reset,
) {
    var a: logic<8>;
    var b: logic<8>;

    // 組み合わせ変数(var + assign の省略形)
    let c: logic<8> = a + 1;

    // コンパイル時定数
    const INIT: logic<8> = 0;

    always_ff {
        if_reset {
            // FF変数(ノンブロッキング)
            a = 0;
        } else {
            // ローカル束縛(ブロッキング、FFではない)
            let temp: logic<8> = b + 1;
            // FF変数(ノンブロッキング)
            a = temp;
        }
    }

    always_comb {
        // 組み合わせ変数(ブロッキング)
        b = c + 1;
    }
}