アトリビュート
アトリビュートは変数宣言などいくつかの宣言に注釈を付けることができます。
sv
アトリビュート
sv
アトリビュートは SystemVerilog のアトリビュートを表し、(* *)
という形式の SystemVerilog アトリビュートに変換されます。
module ModuleA {
#[sv("ram_style=\"block\"")]
let _a: logic<10> = 1;
#[sv("mark_debug=\"true\"")]
let _b: logic<10> = 1;
}
allow
アトリビュート
allow
アトリビュートは指定されたリントチェックを無効化するために使用できます。
module ModuleA {
#[allow(unused_variable)]
let a: logic<10> = 1;
}
指定可能なリント名は以下の通りです。
- unused_variable
- missing_reset_statement
- missing_port
ifdef
/ifndef
/elsif
/else
アトリビュート
ifdef
と ifndef
アトリビュートは定義された値によってコードブロックを有効にするかどうかを制御するために使用することができます。さらに、ifdef
と ifndef
のついたコードブロックに続けてオプションとして elsif
と else
アトリビュートの付いたブロックを書くこともできます。
以下の例はこれらのアトリビュートの使用方法と、各コードブロックが定義された値によって有効になる様子を示しています。
ifdef
/elsif
/else
の順に宣言されたアトリビュート- もし
DEFINE_A
が定義されていれば、#[ifdef(DEFINE_A)]
のついたコードブロック(コードブロックa)が有効になり、#[ifndef(DEFINE_B)]
と#[else]
のついたコードブロック(コードブロックbとc)は無効になります。 DEFINE_A
が定義されておらず、DEFINE_B
が定義されていれば、#[elfif(DEFINE_B)]
のついたコードブロック(コードブロックb)が有効になり、#[ifndef(DEFINE_A)]
と#[else]
のついたコードブロック(コードブロックaとc)は無効になります。DEFINE_A
とDEFINE_B
が定義されていなければ、#[else]
のついたコードブロックが有効になり、#[ifndef(DEFINE_A)]
と#[elsif(DEFINE_B)]
のついたコードブロック(コードブロックaとb)は無効になります。
- もし
ifndef
/else
の順に宣言されたアトリビュート- もし
DEFINE_D
が定義されていなければ、#[ifndef(DEFINE_D)]
のついたコードブロック(コードブロックd)が有効になり、#[else]
のついたコードブロック(コードブロックe)は無効になります。 DEFINE_D
が定義されていれば、#[else]
のついたコードブロック(コードブロックe)が有効になり、#[ifndef(DEFINE_D)]
のついたコードブロック(コードブロックd)は無効になります。
- もし
module ModuleA {
#[ifdef(DEFINE_A)]
{
// コードブロック a
let _a: logic<10> = 1;
}
#[elsif(DEFINE_B)]
{
// コードブロック b
let _a: logic<10> = 2;
}
#[else]
{
// コードブロック c
let _a: logic<10> = 3;
}
#[ifndef(DEFINE_D)]
{
// コードブロック d
let _b: logic<10> = 4;
}
#[else]
{
// コードブロック e
let _b: logic<10> = 5;
}
}
生成されたコードにおける末尾カンマ周りの複雑な調整を回避するため、カンマ区切りリストの最後のアイテムにifdef
をつけることは禁止されています。
expand
アトリビュート
expand
アトリビュートが設定されているとき、modport
のような構造化されたポートはVerilog のポートに展開されます。合成ツールによってはトップモジュールがそのようなポートを含んではならない場合があり、そのような場合にこのアトリビュートを使うことができます。使用可能な引数は以下の通りです。
modport
: ポート方向がmodport
のポートを展開する
interface InterfaceA::<W: u32> {
var ready: logic ;
var valid: logic ;
var data : logic<W>;
modport master {
ready: input ,
valid: output,
data : output,
}
modport slave {
ready: output,
valid: input ,
data : input ,
}
}
#[expand(modport)]
module ModuleA (
slave_if : modport InterfaceA::<8>::slave [4],
master_if: modport InterfaceA::<8>::master [4],
) {
for i in 0..4 :g {
connect slave_if[i] <> master_if[i];
}
}
module ModuleB {
inst a_if: InterfaceA::<8> [4];
inst b_if: InterfaceA::<8> [4];
inst u: ModuleA (
slave_if : a_if,
master_if: b_if,
);
}
align
アトリビュート
align
アトリビュートはフォーマッタの垂直方向の整列を制御することができます。number
が align
の引数として指定されたとき、全ての数値は整列されます。identifier
も使用可能です。
module ModuleA {
let a : logic<32> = 1;
let aa : logic<32> = 1;
let aaa: logic<32> = 1;
let _b: logic = {
a[0] repeat 1, a[0] repeat 1,
aa[1] repeat 8, aa[1] repeat 8,
aaa[2] repeat 16, aaa[2] repeat 16,
};
#[align(number, identifier)]
let _c : logic = {
a [0 ] repeat 1 , a [0 ] repeat 1 ,
aa [1 ] repeat 8 , aa [1 ] repeat 8 ,
aaa[2 ] repeat 16, aaa[2 ] repeat 16,
};
}
fmt
アトリビュート
fmt
アトリビュートはフォーマットの方法を制御することができます。以下の引数がサポートされています。
compact
: 改行なしのコンパクトなフォーマット
module ModuleA {
#[fmt(compact)]
{
inst u1: $sv::Module #( A: 1, B: 2 ) ( x: 1, y: _ );
inst u2: $sv::Module #( A: 1, B: 2 ) ( x: 1, y: _ );
inst u3: $sv::Module #( A: 1, B: 2 ) ( x: 1, y: _ );
inst u4: $sv::Module #( A: 1, B: 2 ) ( x: 1, y: _ );
}
}