クロックドメインアノテーション

モジュール内に複数のクロックがある場合、'a のような明示的なクロックドメインアノテーションが必要です。アノテーションはそれぞれの信号がどのクロックドメインに所属するかを示します。

module ModuleA (
    // クロックドメイン 'a に所属
    i_clk_a: input  'a clock,
    i_dat_a: input  'a logic,
    o_dat_a: output 'a logic,

    // クロックドメイン 'b に所属
    i_clk_b: input  'b clock,
    i_dat_b: input  'b logic,
    o_dat_b: output 'b logic,
) {
    // 同じクロックドメイン内の代入は安全
    assign o_dat_a = i_dat_a;
    assign o_dat_b = i_dat_b;
}

モジュール内にクロックが1つしかない場合、アノテーションは省略できます。

module ModuleA (
    i_clk: input  clock,
    i_dat: input  logic,
    o_dat: output logic,
) {
    assign o_dat = i_dat;
}

'_ は暗黙のクロックドメインを表す特別なクロックドメインです。これは複数のクロックが同じ暗黙のクロックドメインに所属することを示すために使用できます。

module ModuleA (
    // 全ての信号は暗黙のクロックドメインに所属
    i_clk   : input  '_ clock,
    i_clk_x2: input  '_ clock,
    i_dat   : input     logic,
    o_dat   : output    logic,
) {
    assign o_dat = i_dat;
}

インターフェースインスタンスもクロックドメインアノテーションを指定可能です。

module ModuleA {
    inst intf: 'a InterfaceA;
}

interface InterfaceA {}

クロックドメインの推論

クロックドメインアノテーションなしで宣言された変数は、ドメインを自動的に推論できます。ドメインは assign 文の右辺または always_ff ブロックのクロックから推論されます。

ポート宣言は公開インターフェースであり明示的であるべきなので、推論が可能な場合でもポート宣言のクロックドメインアノテーションは省略できません。

module ModuleA (
    i_clk_a: input  'a clock,
    i_rst_a: input  'a reset,
    i_dat_a: input  'a logic,
    o_dat_a: output 'a logic,
    i_clk_b: input  'b clock,
    i_rst_b: input  'b reset,
    i_dat_b: input  'b logic,
    o_dat_b: output 'b logic,
) {
    // assignの右辺から 'a と推論
    var x: logic;

    assign x       = i_dat_a;
    assign o_dat_a = x;

    // always_ffのクロックから 'b と推論
    var y: logic;
    always_ff (i_clk_b, i_rst_b) {
        if_reset {
            y = 0;
        } else {
            y = i_dat_b;
        }
    }
    assign o_dat_b = y;
}