bit [3:0] nibble[]; integer mem[][]; time t1[10][]; realtime t2[][10]; longint t3[][];
module dynamic_array; bit [3:0] nibble[]; integer mem[][]; time t1[10][]; realtime t2[][10]; longint t3[][]; initial begin $display("nibble.size()=%d",nibble.size()); $display("mem.size()=%d",mem.size()); $display("t1.size()=%d",t1.size()); $display("t1[0].size()=%d",t1[0].size()); $display("t2.size()=%d",t2.size()); $display("t3.size()=%d",t3.size()); end
***** Veritak SV Engine Version 0.431 Build Oct.15.2011 ***** nibble.size()= 0 mem.size()= 0 t1.size()= 10 t1[0].size()= 0 t2.size()= 0 t3.size()= 0 ---------- シミュレーションを終了します。time=0nst1は、time[ ] を要素として10個(固定)持つ配列になります。この場合、10個は、実行前に確保されるので、10 の表示になります。しかし、要素の一つである、t1[0] についてみれば、[ ] ですから、未だメモリは確保されずそのサイズは0になります。このように[ ]次元では、実行時にメモリを確保してから使う必要があります。
module dynamic_array; bit [3:0] nibble[]; integer mem[][];// [] ごとにnew が必要 integer mem_fixed[10][3]; time t1[2][]; realtime t2[][3]; longint t3[][]; int arr1 [][2][3]; initial begin nibble=new [4]; foreach (nibble[i]) $display(" nibble[%1d]=%b",i,nibble[i]); $display(""); mem=new [10]; mem[1]=new [3]; foreach (mem[i,j]) $display(" mem[%1d][%1d]=%b",i,j,mem[i][j]); $display(""); foreach (mem_fixed[i,j]) $display(" mem_fixed[%1d][%1d]=%b",i,j,mem_fixed[i][j]); $display(""); t1[0]=new[3]; foreach (t1[i,j]) $display(" t1[%1d][%1d]=%b",i,j,t1[i][j]); $display(""); t2=new[4]; foreach (t2[i,j]) $display(" t2[%1d][%1d]=%f",i,j,t2[i][j]); $display(""); arr1=new[3]; foreach (arr1[i,j,k]) $display(" arr1[%1d][%1d][%1d]=%b",i,j,k,arr1[i][j][k]); end endmodule
***** Veritak SV Engine Version 0.431 Build Oct.15.2011 *****
nibble[0]=0000
nibble[1]=0000
nibble[2]=0000
nibble[3]=0000
mem[1][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem[1][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem[1][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[0][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[0][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[0][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[1][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[1][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[1][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[2][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[2][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[2][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[3][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[3][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[3][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[4][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[4][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[4][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[5][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[5][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[5][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[6][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[6][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[6][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[7][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[7][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[7][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[8][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[8][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[8][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[9][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[9][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mem_fixed[9][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
t1[0][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
t1[0][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
t1[0][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
t2[0][0]=0.000000
t2[0][1]=0.000000
t2[0][2]=0.000000
t2[1][0]=0.000000
t2[1][1]=0.000000
t2[1][2]=0.000000
t2[2][0]=0.000000
t2[2][1]=0.000000
t2[2][2]=0.000000
t2[3][0]=0.000000
t2[3][1]=0.000000
t2[3][2]=0.000000
arr1[0][0][0]=00000000000000000000000000000000
arr1[0][0][1]=00000000000000000000000000000000
arr1[0][0][2]=00000000000000000000000000000000
arr1[0][1][0]=00000000000000000000000000000000
arr1[0][1][1]=00000000000000000000000000000000
arr1[0][1][2]=00000000000000000000000000000000
arr1[1][0][0]=00000000000000000000000000000000
arr1[1][0][1]=00000000000000000000000000000000
arr1[1][0][2]=00000000000000000000000000000000
arr1[1][1][0]=00000000000000000000000000000000
arr1[1][1][1]=00000000000000000000000000000000
arr1[1][1][2]=00000000000000000000000000000000
arr1[2][0][0]=00000000000000000000000000000000
arr1[2][0][1]=00000000000000000000000000000000
arr1[2][0][2]=00000000000000000000000000000000
arr1[2][1][0]=00000000000000000000000000000000
arr1[2][1][1]=00000000000000000000000000000000
arr1[2][1][2]=00000000000000000000000000000000
module dynamic_array; int arr1 [][1][3] = new [2]; int arr2 [][] = new [2]; initial begin $display("arr1.size()=%d",arr1.size()); $display("arr2.size()=%d",arr2.size()); end endmodule
***** Veritak SV Engine Version 0.431 Build Oct.15.2011 *****
arr1.size()= 2
arr2.size()= 2
---------- シミュレーションを終了します。time=0ns
上例の最後に下記を追加して、コールしてみます。
function void delete(); $display("delete method "); arr1.delete(); foreach (arr1[i,j,k]) $display(" arr1[%1d][%1d][%1d]=%b",i,j,k,arr1[i][j][k]); $display(""); t2.delete(); foreach (t2[i,j]) $display(" t2[%1d][%1d]=%f",i,j,t2[i][j]); $display(""); t1[0].delete(); foreach (t1[i,j]) $display(" t1[%1d][%1d]=%b",i,j,t1[i][j]); $display(""); mem[2]=new[3]; mem[1].delete(); foreach (mem[i,j]) $display(" mem[%1d][%1d]=%b",i,j,mem[i][j]); $display(""); endfunction
deleteされた次元の配列は、サイズが0になります。(foreachは、ループが周らなくなり表示されません。)
結果です。
mem[2][0]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx mem[2][1]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx mem[2][2]=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4)代入
アンパックド配列間の代入が可能になっています。ただし、条件が二つあります。
下の例で見ましょう。
module queue16; int A[2][10:1]; int B[] = new[10]; int C[] = new[8]; int D [3][][]; `define GEN_ERROR initial begin D[2] = new [2]; D[2][0] = new [10]; D[2][1] = new [10];//LRM ERROR ? A[1] = B; // OK. Both are arrays of 10 ints `ifdef GEN_ERROR A[1] = C; // type check error: different sizes (10 vs. 8 ints) `endif A = D[2]; // A foreach (D[i,j,k]) $display(" D[%1d][%1d][%1d]=%b",i,j,k,D[i][j][k]); end endmodule
最初の
A[1] = B;
は、A[1]は、10個のint固定配列です。一方、Bは、10個のダイナミック配列です。両方とも一次元、サイズも10個、タイプもint
で、条件にマッチするので
代入可能です。
次の
A[1] = C;
は、Cは8個のint ダイナミック配列ですので、サイズが合いません。実行時エラーになります。
***** Veritak SV Engine Version 0.431 Build Oct.15.2011 ***** G:\sv_test\queue\queue16.sv(16)::Fatal Error : array size is not matched.
次の
A = D[2];
は、[2][10] という次元と要素をどちらも、持つので、代入可能です。なお、上記例は、ほぼ、LRM P1800
に載っている例と同じですが、
LRMの方は、
D[2][1] =..;
の記述がありませんでした。(これが無いとすると、(16)行のエラーと同様、サイズがマッチしない旨の実行時エラーとなるはずです。誤植だと思います。)
ifdef 定義をオフにした場合の実行結果です。
***** Veritak SV Engine Version 0.431 Build Oct.15.2011 *****
D[2][0][0]=00000000000000000000000000000000
D[2][0][1]=00000000000000000000000000000000
D[2][0][2]=00000000000000000000000000000000
D[2][0][3]=00000000000000000000000000000000
D[2][0][4]=00000000000000000000000000000000
D[2][0][5]=00000000000000000000000000000000
D[2][0][6]=00000000000000000000000000000000
D[2][0][7]=00000000000000000000000000000000
D[2][0][8]=00000000000000000000000000000000
D[2][0][9]=00000000000000000000000000000000
D[2][1][0]=00000000000000000000000000000000
D[2][1][1]=00000000000000000000000000000000
D[2][1][2]=00000000000000000000000000000000
D[2][1][3]=00000000000000000000000000000000
D[2][1][4]=00000000000000000000000000000000
D[2][1][5]=00000000000000000000000000000000
D[2][1][6]=00000000000000000000000000000000
D[2][1][7]=00000000000000000000000000000000
D[2][1][8]=00000000000000000000000000000000
D[2][1][9]=00000000000000000000000000000000
---------- シミュレーションを終了します。time=0ns
次の例は、ダイナミック配列に対する代入です。ダイナミック配列に対する代入の場合、サイズ一致の制限はありません。サイズに関係なく、自由に代入できます。
例えば、ダイナミック配列Bに対する代入は、
B = A;
このとき、B=new [A.size()];が、暗黙的に実行されます。これにより、今までのBの内容は、捨てられて、新しい領域がA.size()分確保されてます。
その後に、Aの各要素がBにコピーされます。
B= new [C.size()](C);
は、B=Cに等価です。まず、Cと同じ領域だけメモリを確保して、その後にCの内容をBにコピーします。
このように、ダイナミック配列に対するアンパックド配列次元の代入は、暗黙的にnew 動作が入っていることに注意してください。
確保される領域の大きさと、内容を別に制御したい場合には、次のようにします。
B=new [B.size()*2](B);
は、今までのBのサイズの2倍の新しい領域を確保します。このとき、新しい領域は、default値で埋められます。その後に、Bの内容を新しい領域にコピーします。
B=new [B.size()/2](B);
は、Bのサイズの1/2の新しい領域を確保します。その後にBの内容が新しい領域にコピーされます。結果的に、トランケートされた内容になります。
module queue17;
int A[10:1]; // fixed-size array of 100 elements
int B[]; // empty dynamic array
int C[] = new[8]; // dynamic array of size 8
initial begin
B = A;
foreach (B[i]) $display(" B[%1d]=%1d",i,B[i]);
$display("");
B = C;
foreach (B[i]) $display(" B[%1d]=%1d",i,B[i]);
$display("");
foreach (C[i]) C[i]=i;
B= new [C.size()](C);//B=C
foreach (B[i]) $display(" B[%2d]=%2d",i,B[i]);
$display("");
B=new [B.size()*2](B);
foreach (B[i]) $display(" B[%2d]=%2d",i,B[i]);
$display("");
B=new [B.size()/2](B);
foreach (B[i]) $display(" B[%2d]=%2d",i,B[i]);
$display("");
end
endmodule
実行結果です。
***** Veritak SV Engine Version 0.431 Build Oct.15.2011 *****
B[0]=0
B[1]=0
B[2]=0
B[3]=0
B[4]=0
B[5]=0
B[6]=0
B[7]=0
B[8]=0
B[9]=0
B[0]=0
B[1]=0
B[2]=0
B[3]=0
B[4]=0
B[5]=0
B[6]=0
B[7]=0
B[ 0]= 0
B[ 1]= 1
B[ 2]= 2
B[ 3]= 3
B[ 4]= 4
B[ 5]= 5
B[ 6]= 6
B[ 7]= 7
B[ 0]= 0
B[ 1]= 1
B[ 2]= 2
B[ 3]= 3
B[ 4]= 4
B[ 5]= 5
B[ 6]= 6
B[ 7]= 7
B[ 8]= 0
B[ 9]= 0
B[10]= 0
B[11]= 0
B[12]= 0
B[13]= 0
B[14]= 0
B[15]= 0
B[ 0]= 0
B[ 1]= 1
B[ 2]= 2
B[ 3]= 3
B[ 4]= 4
B[ 5]= 5
B[ 6]= 6
B[ 7]= 7
---------- シミュレーションを終了します。time=0ns
5)サブルーチンに対する代入
制限は、上で述べたことに同じです。
module queue18; int b[4:1] ='{1,2,3,4}; int c[5:2] ='{5,4,3,2}; int d[]='{6,5,4,3}; initial begin t(b); t(c); t(d); t_dynamic(b); t_dynamic(c); t_dynamic(d); d=new [5](d); t_dynamic(d); t(d); end task t( input int mem[4:1]) ; foreach (mem[i]) $display("mem[%1d]=%1d",i,mem[i]); $display(""); endtask task t_dynamic( inputint dmem[]) ; foreach (dmem[i]) $display("dmem[%1d]=%1d",i,dmem[i]); $display(""); endtask endmodule
実行結果です。
宣言の昇降順によらず、宣言順に各要素が代入されます。
d[] は、 内部的には、d[0 :d.size()-1] で扱われます。
d[0] -> mem[4]
d[1] -> mem[3]
d[2] -> mem[2]
d[1] -> mem[1]
という具合にコピーされます。
ダイナミック配列から固定サイズ配列にコピーされるときに、要素数が合わないと、下記の最後のように、実行時エラーとなります。
***** Veritak SV Engine Version 0.431 Build Oct.15.2011 *****
mem[4]=1
mem[3]=2
mem[2]=3
mem[1]=4
mem[4]=5
mem[3]=4
mem[2]=3
mem[1]=2
mem[4]=6
mem[3]=5
mem[2]=4
mem[1]=3
dmem[0]=1
dmem[1]=2
dmem[2]=3
dmem[3]=4
dmem[0]=5
dmem[1]=4
dmem[2]=3
dmem[3]=2
dmem[0]=6
dmem[1]=5
dmem[2]=4
dmem[3]=3
dmem[0]=6
dmem[1]=5
dmem[2]=4
dmem[3]=3
dmem[4]=0
G:\sv_test\queue\qiueue18.sv(20)::Fatal Error : array size is not matched.
ストリング配列の例です。
module queue18; string b[4:1] ='{"a","b","c","d"}; string c[5:2] ='{"d","e","f","g"}; string d[]= '{"h","i","j","k"}; initial begin t(b); t(c); t(d); t_dynamic(b); t_dynamic(c); t_dynamic(d); d=new [5](d); t_dynamic(d); t(d); end task t( input string mem[4:1]) ; foreach (mem[i]) $display("mem[%1d]=%s",i,mem[i]); $display(""); endtask task t_dynamic( inputstring dmem[]) ; foreach (dmem[i]) $display("dmem[%1d]=%s",i,dmem[i]); $display(""); endtask endmodule
実行結果です。
***** Veritak SV Engine Version 0.431 Build Oct.15.2011 ***** mem[4]=a mem[3]=b mem[2]=c mem[1]=d mem[4]=d mem[3]=e mem[2]=f mem[1]=g mem[4]=h mem[3]=i mem[2]=j mem[1]=k dmem[0]=a dmem[1]=b dmem[2]=c dmem[3]=d dmem[0]=d dmem[1]=e dmem[2]=f dmem[3]=g dmem[0]=h dmem[1]=i dmem[2]=j dmem[3]=k dmem[0]=h dmem[1]=i dmem[2]=j dmem[3]=k dmem[4]= G:\sv_test\queue\qiueue20.sv(21)::Fatal Error : array size is not matched.