型推論
型注釈やジェネリック引数は、周辺のコードから導出できる場合に省略できることがあります。この章ではサポートされるパターンをまとめます。
モジュール/インターフェース/関数のポート宣言や関数の戻り値型は、型が推論可能であっても、インターフェースを明確に保つため引き続き型注釈が必要です。
変数の型推論
var や let 宣言、および const 宣言の型注釈は、型が推論可能な場合に省略できます。
型を持たない var 宣言では、assign、always_comb、always_ff を通じた最初の代入から型が推論されます。let および const 宣言では、右辺の式から型が推論されます。
module ModuleA {
let _a: logic<8> = 0;
// `_a` の型から推論される。
let _b = _a;
// ビット幅付きリテラルから推論される。
let _c = 8'd255;
// 最初の代入から推論される。
var _d;
assign _d = _a;
// always_comb 内の最初の代入から推論される。
var _e;
always_comb {
_e = _a;
}
// `const` も推論をサポートする。
const _F = 16'd100;
}
以下の式は型推論の元として使用できます。
- 変数参照
- ビット幅付き数値リテラル(例:
8'd10) - 括弧で囲まれた式(内側の式へ再帰的に推論)
- 関数呼び出し(戻り値の型から推論)
以下の式は SystemVerilog のビット幅評価規則に依存し、ユーザーにとって予期しにくい結果になるため、サポートされません。
- ビット幅なし数値リテラル(例:
10、'0) - 演算子を含む式(例:
_a + 1) - 連結(例:
{_a, _a}) if/case式
同一の var に対する複数の代入で推論される型が一致しない場合、type_inference_conflict として報告されます。サポートされていない式の場合は type_inference_not_supported が報告されます。いずれの場合も、明示的な型注釈を加えればエラーは解消されます。
ジェネリック引数の推論
ジェネリック関数では、関数の引数からジェネリック引数を推論できる場合、::<> 後の実引数を省略できます。推論は各実引数の宣言型を用いてジェネリックパラメータを解決します。
module ModuleA {
function FuncId::<T: u32> (
x: input logic<T>,
) -> logic<T> {
return x;
}
function FuncWide::<T: u32> (
x: input logic<T>,
) -> logic<T + 1> {
return {1'b0, x};
}
let _a: logic<8> = 0;
let _b: logic<16> = 0;
// 実引数の宣言された幅から T が 8 / 16 に推論される。
let _r1: logic<8> = FuncId(_a);
let _r2: logic<16> = FuncId(_b);
// `T + 1` パターン: 実引数の幅 8 から T = 8 が解決される。
let _rw: logic<9> = FuncWide(_a);
}
実引数の幅を変数宣言から決定できない場合(例: ビット幅付きリテラルを渡した場合)、推論は失敗します。その場合は明示的なジェネリック引数が必要です。詳細は generic_inference_failed を参照してください。