アサインメント パターン (assignment pattern)

アサインメント パターンとは、配列の要素や、構造体のメンバーをパターンとして記述するやり方です。複雑な初期化を一回で記述できます。
VerilogHDLの連接{ } に似ていますが、全くの別物です。この仕様は、SVでも新しい仕様です。(仕様の変遷がありました。3.1aでは、連接で記述していました。)

パターンの記述としては、下のように '{ } アポストロフィの後に{ } で、パターンを囲みます。

1
2
3
4
5
6
7
8
module assignment_pattern_test;


bit unpackedbits [1:0] = '{1,1};

	initial $display("unpackedbits=%p",unpackedbits);

endmodule

%p は、アサインメントパターンとして出力できます。


配列のアサインメントパターン


左側(LHS)の配列数と、右側(RHS)のパターン数は、一致している必要があります。
また、配列宣言に関係なく、下のようにパターンの並びを維持したまま、LHSに代入されます。

RHSのパターンは、LHSのビット幅を参照して、自動的に拡張、切捨てが行われます。これは、VerilogHDLの通常の代入(アサインメント)と同じです。
下の例では、RHSは、符号付きです。一方LHSは、32ビットなので、符号拡張された結果が各配列要素に32ビット値として代入されます。


1
2
3
4
5
6
7
8
9
module assignment_pattern_test2;


	int unpackedints  [1:0] = '{1'sb1, 3'sb110};
	int unpackedints2 [0:1] = '{1'sb1, 3'sb110};

	initial $display("unpackedints=%p %p",unpackedints,unpackedints2);

endmodule


1
2
3
4
5
***** Veritak SV32 Engine Version 431 Build Nov 29 2012*****

unpackedints='{-1,-2} '{-1,-2}

---------- シミュレーションを終了します。time=0ns


パターンの繰り返し

パターンのを指定回数分、繰り返すことが出来ます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
module assignment_pattern_test3;
parameter bit signed Y=1;


bit unpackedbits [1:0] ='{ 2{Y}} ; // same as '{y, y}
int n[1:2][1:3] = '{ 2{ '{ 3 {Y} } } };//same as '{'{y,y,y},'{y,y,y}}


	initial begin
		$display("unpackedbits=%p" ,unpackedbits);
		$display("%p",n);
	end

endmodule


結果です。
リピート項は、定数である必要があります。また、展開した後の要素数は、LHSの配列幅と一致している必要があります。

1
2
3
4
5
6
***** Veritak SV32 Engine Version 431 Build Nov 29 2012*****

unpackedbits='{1,1}
'{'{-1,-1,-1},'{-1,-1,-1}}

---------- シミュレーションを終了します。time=0ns


この形式では、多次元のダイナミックアレーやキューの初期化も行うことが出来ます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
module assignment_pattern_test3a;

parameter bit signed Y=1;
parameter string S="dead_beef", A="tak.sugawara";

bit unpackedbits [] ='{ 2{Y}} ; 
int n[][1:3] = '{ 2{ '{ 3 {Y} } } };
string str_array [$][$]= '{ 
						'{A,A},
						'{ 3 {S} } 
					  };

	initial begin
		$display("unpackedbits=%p" ,unpackedbits);
		$display("%p",n);
		$display("%p",str_array);

	
	end		

endmodule


1
2
3
4
5
6
7
***** Veritak SV32 Engine Version 431 Build Nov 29 2012*****

unpackedbits='{1,1}
'{'{-1,-1,-1},'{-1,-1,-1}}
'{'{"tak.sugawara","tak.sugawara"},'{"dead_beef","dead_beef","dead_beef"}}

---------- シミュレーションを終了します。time=0ns



default :による指定

下のようにdefault パターンを指定することも出来ます。

1
2
3
4
5
6
7
8
module assignment_pattern_test4;

int  unpackedints[5] = '{default:2};


	initial $display("%p",unpackedints);

endmodule



1
2
3
4
5
***** Veritak SV32 Engine Version 431 Build Nov 30 2012*****

'{2,2,2,2,2}

---------- シミュレーションを終了します。time=0ns


defaultの次元が、要素の次元ではないときには、要素次元になるまで、次元を下って行き、要素次元のところで、アサインメント動作をおこないます。

1
2
3
4
5
6
7
8
module assignment_pattern_test4a;

int  unpackedints2[5][2][3]= '{default:2};


	initial $display("%p",unpackedints2);

endmodule


このように、深い次元でも一回で初期化出来るので便利です。

1
2
3
4
5
***** Veritak SV32 Engine Version 431 Build Nov 30 2012*****

'{'{'{2,2,2},'{2,2,2}},'{'{2,2,2},'{2,2,2}},'{'{2,2,2},'{2,2,2}},'{'{2,2,2},'{2,2,2}},'{'{2,2,2},'{2,2,2}}}

---------- シミュレーションを終了します。time=0ns




Indexによる指定

配列の場合には、Indexを指定することも出来ます。

1
2
3
4
5
6
7
8
module assignment_pattern_test4;

	int  unpackedints[5:1]= '{  2:2, 3:3 ,default:99};


	initial $display("%p",unpackedints);

endmodule


1
2
3
4
5
***** Veritak SV32 Engine Version 431 Build Nov 30 2012*****

'{99,99,3,2,99}

---------- シミュレーションを終了します。time=0ns


Indexによる指定は、defaultによる指定よりも優先します。

1
2
3
4
5
6
7
8
module assignment_pattern_test4;

	int  unpackedints[5]= '{ 4: 4, 3:3, 2:20, 1:1,0:0  ,default:2};


	initial $display("%p",unpackedints);

endmodule


上の例では、default:を適用する場所がありませんが、特に問題ありません。

1
2
3
4
5
***** Veritak SV32 Engine Version 431 Build Nov 30 2012*****

'{0,1,20,3,4}

---------- シミュレーションを終了します。time=0ns

Indexによる指定/defaultによる指定は、通常のパターンと混在させることはできません。
下記は、コンパイルエラーになります。

1
2
3
4
5
6
7
8
module assignment_pattern_test4e;

	int  unpackedints[5:1]= '{  1 ,default:99};


	initial $display("%p",unpackedints);

endmodule

また、Indexによる指定/defaultによる指定は、固定次元でのみ可能です。

1
2
3
4
5
6
7
8
module assignment_pattern_test4d;

	int  unpackedints2[][5]= '{  '{4: 4, 3:3, default:99  }  ,'{1:0,default:2}};


	initial $display("%p",unpackedints2);

endmodule


上で、Index/default指定を行っているのは、最下位次元で固定の要素数を持ちます。
(上の次元は、[] なので、指定することができません。)

1
2
3
4
5
***** Veritak SV32 Engine Version 431 Build Nov 30 2012*****

'{'{99,99,99,3,4},'{2,0,2,2,2}}

---------- シミュレーションを終了します。time=0ns



構造体のアサインメントパターン


配列と同様ですが、Indexによる指定はありませんが、代わりに構造体においては、メンバー名による指定(12行目)になります。メンバー名による指定を行った場合には、default: を併用することが出来ます。(18行目)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
module mod1;
	typedef struct {
		int x;
		int y;
	} st;
	st s1;
	int k = 1;
	initial begin
 		s1 = '{1, 2+k}; // by position
		$display( "s1=%p",s1);

		s1 = '{x:2, y:3+k}; // by name
		$display( "s1=%p",s1);

		s1='{default: -10};
		$display( "s1=%p",s1);
	
		s1='{ x:2, default:-20};
		$display( "s1=%p",s1);
		$finish;
	end
endmodule


また、%pでは、下のようにメンバー名も出力されます。

1
2
3
4
5
6
7
***** Veritak SV32 Engine Version 431 Build Dec  2 2012*****

s1='{x:1,y:3}
s1='{x:2,y:4}
s1='{x:-10,y:-10}
s1='{x:2,y:-20}
Info: $finishコマンドを実行します。time=0ns



ネストした構造体への代入

下のようにネストした構造体の初期化を行うことが出来ます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
module assignment_pattern_test6;

typedef struct {
		int B, C;
	} SubType;


typedef struct {
		int A;
		SubType BC1,BC2;	
} S;
	S ABC;

initial begin
ABC = '{A:1, BC1:'{B:2, C:3}, BC2:'{B:4,C:5}};
$display("ABC=%p",ABC);

ABC= '{default:10};
$display("ABC=%p",ABC);
end

endmodule


また、default:は、下のように4行目のようにネストした構造体にも作用します。

1
2
3
4
5
6
***** Veritak SV32 Engine Version 431 Build Dec  2 2012*****

ABC='{A:1,BC1:'{B:2,C:3},BC2:'{B:4,C:5}}
ABC='{A:10,BC1:'{B:10,C:10},BC2:'{B:10,C:10}}

---------- シミュレーションを終了します。time=0ns



構造体の配列

アサインメントパターンは、構造体配列にも適用可能です。 配列は、ダイナミック/キューであってもOKです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module assignment_pattern_test6a;

typedef struct {
		int B, C;
	} SubType;


typedef struct {
		int A;
		SubType BC1,BC2;	
} S;
	S ABC[],AB_Fixed[3];
	SubType S1[$];
initial begin

S1='{ 3 {'{B:2,C:3}}};
$display("S1=%p",S1);

ABC = '{ 3{ '{A:1, BC1:'{B:2, C:3}, BC2:'{B:4,C:5}}}};
$display("ABC=%p",ABC);

AB_Fixed= '{default:10};
$display("ABC=%p",ABC);

end

endmodule


ただし、default: が使えるのは、固定次元配列でのみです。

1
2
3
4
5
6
7
***** Veritak SV32 Engine Version 431 Build Dec  2 2012*****

S1='{'{B:2,C:3},'{B:2,C:3},'{B:2,C:3}}
ABC='{'{A:1,BC1:'{B:2,C:3},BC2:'{B:4,C:5}},'{A:1,BC1:'{B:2,C:3},BC2:'{B:4,C:5}},'{A:1,BC1:'{B:2,C:3},BC2:'{B:4,C:5}}}
ABC='{'{A:1,BC1:'{B:2,C:3},BC2:'{B:4,C:5}},'{A:1,BC1:'{B:2,C:3},BC2:'{B:4,C:5}},'{A:1,BC1:'{B:2,C:3},BC2:'{B:4,C:5}}}

---------- シミュレーションを終了します。time=0ns


type (型)による指定


次の例は、time 型を指定しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
module assignment_pattern_test7a;

typedef struct {
	integer a;
	time t1;
} sa;
sa s1;

initial begin

	s1= '{time :20,default:0};
	$display("s1=%p",s1);


	s1= '{t1:30,time :20,default:1};
	$display("s1=%p",s1);


end

endmodule

t1は、20がアサインされ、aは、default である0がアサインされています。名前指定がある場合には、名前指定が優先されます。

1
2
3
4
***** Veritak SV32 Engine Version 431 Build Dec  2 2012*****

s1='{a:0,t1:20}
s1='{a:1,t1:30}


type のマッチには、符号・プリミティブ型・ビット幅 の一致が必要

3行目のtypedef で、int unsigned のユーザ定義型を定義しています。この型に対して17行目で、3をアサインするように指示しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
module assignment_pattern_test7b;

typedef int unsigned uint;

typedef struct {
	bit b;
	bit [32:1] u32;
        bit signed [31:0] s32;
	int i32;
	integer a;

} sa;
sa s1;

initial begin

	s1= '{ uint: 3, bit :1,default:0};
	$display("s1=%p",s1);




end

endmodule

実は、これに対応するのは、この構造体中、bit [32:1] u32 だけです。

1
2
3
4
5
***** Veritak SV32 Engine Version 431 Build Dec  2 2012*****

s1='{b:1,u32:3,s32:0,i32:0,a:0}

---------- シミュレーションを終了します。time=0ns


intは、符号付2値32ビットですので、bit signed [31:0] と等価です。上のユーザ定義は、bit [32:1]ではありますが、ビット幅は、bit [31:0] と同じ32ビットで等価です。しかも、”符号なし”指定なのでu32がマッチするという訳です。

このように、type指定を行う場合には、プリミティブな定義まで辿って型の等価性を考える必要があります。

表記型 プリミティブ型 default符号 ビット幅
bit 2値  なし 1
reg/logic 4値 なし 1
byte 2値 あり 8
shortint 2値 あり 16
int 2値 あり 32
integer 4値 あり 32
longint 2値 あり 64
time 4値 なし 64
real /realtime 浮動小数 あり 64
shortreal 浮動小数 あり 32
string string なし -
chandle chandle なし 32(64)



アサインメントパターンは、大別すると順番指定と、Index/メンバー指定の2種類あり、以下のようにまとめられます。
アサインメントパターン 方式
順番指定 配列の要素数/構造体メンバー数 分のパターン指定が必要。 LHSは、ダイナミック配列/キューでもよい。(パターン数分が、自動で確保される。  LHSが固定次元であるならば、パターン数と、配列の要素数は、各次元で一致していることが必要。)
Index/メンバー名指定 Index/メンバー名指定> (型指定) > (default 指定) の優先順で、アサインされる。 defaultは、末端次元まで効く。LHSが、ダイナミック配列/キューのとき、(要素数が定まらないので、)定義できない。