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