Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

代入のセマンティクス

Verylはすべての代入に単一の = 演算子を使用します。実際のセマンティクス — ブロッキングかノンブロッキングか — は代入コンテキストにより自動的に決定されます。これにより、設計者が手動で従うべきSystemVerilogのベストプラクティスが強制されます。

ブロッキング代入

always_comb ブロックと assign 宣言では、=ブロッキング代入を行います。代入された値は同一評価パス内の後続の読み取りから即座に参照可能です。

module ModuleA {
    let a: logic<8> = 1;
    var b: logic<8>;
    var c: logic<8>;

    always_comb {
        b = a + 1; // b は即座に 2 に更新される
        c = b + 1; // c は b の新しい値 (2) を読むため、c = 3
    }
}

ノンブロッキング代入

always_ff ブロック内では、モジュールレベル変数に対する =ノンブロッキング代入を行います。代入された値はNBA更新フェーズにスケジュールされ、FFコミットまで反映されません。

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

    always_ff {
        // a.next = 1(このフェーズ中 current の a は変化しない)
        a = 1;
        // a.current を読む(a.next ではない)ため、b.next = a.current + 1
        b = a + 1;
    }
}

always_ff 内のローカル束縛

always_ff 内の let 束縛は常にブロッキングセマンティクスを使用します。ローカル束縛はブロック内の一時的な値であり、フリップフロップにマップされることはありません。

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

    always_ff {
        // ブロッキング:doubled は即座に利用可能
        let doubled: logic<8> = a * 2;
        // ノンブロッキング:result.next = doubled + 1
        result = doubled + 1;
    }
}

always_ff 内の関数呼び出し

always_ff から呼び出される関数は、関数外の HDL オブジェクトへ書き込むことはできません。関数によって書き込まれる output 引数は、always_ff プロセス内で宣言された変数に接続する必要があります。その結果は、プロセスのノンブロッキング代入セマンティクスに従って明示的に代入できます。

module ModuleA (
    i_clk : input  clock   ,
    a     : input  logic<8>,
    result: output logic<8>,
) {
    function increment (
        value: input  logic<8>,
        next : output logic<8>,
    ) {
        next = value + 1;
    }

    always_ff {
        var next: logic<8>;
        increment(a, next);
        result = next;
    }
}

この制限により、シミュレーションサイクルに参加する HDL オブジェクトへのすべての書き込みが always_ff プロセス内に明示されます。関数は上記のように、ローカル変数と書き込み対象の output 引数を変更できます。$display$assert などのシステム関数は、このような HDL オブジェクトを書き込まないため、この制限の対象外です。

SystemVerilogへの対応

VerylコンテキストVeryl構文SystemVerilog相当
always_combx = expr;x = expr;(ブロッキング)
assignassign x = expr;assign x = expr;(continuous assignment)
always_ff、モジュールレベル変数x = expr;x <= expr;(ノンブロッキング)
always_ff、ローカル letlet x: T = expr;x = expr;(ブロッキング)
always_ff、複合代入x += expr;x <= x + expr;(ノンブロッキング)