systemverilog 学習 --- 配列演算 (2)

配列縮小法

systemverilog によって提供されるこれらのメソッドは、アンパックされた配列に対して動作し、配列全体を 1 つの値に減らすことができます。組み込みメソッドは次のとおりです。

和() 配列内のすべての要素の合計を返します。
製品() 配列内のすべての要素の積を返します。
そして() 配列要素の AND を返します
または() 配列内のすべての要素の OR を返します。
xor() 配列内のすべての要素の XOR を返します。
module fixedsize_array;

    //declaration of array's
    int array_1[4];
    int t_sum;
    int t_product;

    initial begin
        //array initialization
        array_1 = '{
    
    1,2,3,4};

        t_sum = array_1.sum();          //t_sum = 1+2+3+4
        $display("Sum of array_a is \t %0d", t_sum);

        t_product = array_1.product();  //t_product = 1*2*3*4
        $display("product of array_1 is \t%0d", t_product);
    end


endmodule

上の例は sum() メソッドと product メソッドを示しています。Sum はすべての要素の合計であり、product はすべての要素の積です。
ここに画像の説明を挿入します
and、or、および xor メソッドはすべてビット演算であり、すべての要素値に対してビットごとの AND、ビットごとの OR、またはビットごとの XOR を実行します。
with 演算子を使用して、配列内の要素に対して必要な操作を実行することもできます。

module fixedsize_array;

    //declaration of array's
    int array_1[4];
    int t_sum;
    int t_product;

    initial begin
        //array initialization 
        array_1 = '{
    
    1,2,3,4};
        
        t_sum = array_1.sum with (item * 2);
        //t_sum = (1*2) + (2*2) + (3*2) + (4*2)
        $display("Sum of array_1 is \t %0d", t_sum);

        t_product = array_1.product with (item+2);
        //t_product = (1+2)*(2+2)*(3+2)*(4+2) = 3*4*5*6
        $display("product of array_1 is \t %0d", t_product);
    end

endmodule

上記の例では、配列内の要素はそれぞれ 2 で乗算され、2 で加算されます。実行結果は以下の通りです。
ここに画像の説明を挿入します

配列ロケーターメソッド

配列の位置決めメソッドは、配列要素のインデックスを見つけるのに役立ちます。このタイプのメソッドは、アンパックされた配列とキューで動作できます。これらのメソッドの戻り値の型はキューです。配列の対応する要素またはインデックスは、式を通じて見つけることができます。したがって、インデックスを検索するか要素を検索するかによって、要素検索とインデックス検索に分類できます。
要素ファインダー

探す() 式に一致するすべての要素を検索します
find_first() 式を満たす最初の要素を見つけます
find_last() 式を満たす最後の要素を見つけます
分() 配列内の最小の要素を見つける
最大() 配列内の最大の要素を見つける
個性的() 配列内で一意の値を持つ要素を検索する

**インデックスファインダー**

find_index 式を満たすすべてのインデックスを検索します
find_first_index() 指定された式を満たす最初の要素のインデックスを返します。
find_last_index 指定された式を満たす最後の要素のインデックスを返します。
unique_index() 一意の値を持つ要素のインデックスを返します。
class packet;

    int a;
    int b;

    function void display();
        $display("\tValue of a = %0d", a);
        $display("\tValue of b = %0d", b);
    endfunction

endclass

module assoc_array;
//declaration of array
packet  assoc_array[*]  ;
packet  pkt             ;
int     count           ;
int     qu[$]           ;
int     tmp_var         ;

initial begin
    
    pkt = new();
    pkt.a = 8;
    pkt.b = 3;
    assoc_array[2] = pkt;

    pkt = new();
    pkt.a = 0;
    pkt.b = 6;
    assoc_array[5] = pkt;

    pkt = new();
    pkt.a = 2;
    pkt.b = 6;
    assoc_array[6] = pkt;

    pkt = new();
    pkt.a = 1;
    pkt.b = 6;
    assoc_array[9] = pkt;
    //==========================================================================
    //========== Find Index Method ===========
    //==========================================================================

    //type-1:returning one matching index
    qu = assoc_array.find_index with (item.a == 'h2);
    count = qu.size();

    for(int i=0; i<count; i++)begin
        tmp_var = qu.pop_front();
        $display("Index of Asoc Array for a == 2 is %0d", tmp_var);
    end

    //type-2:returning multiple matching index
    qu = assoc_array.find_index with (item.b == 6);
    count = qu.size();

    for(int i = 0; i < count; i++)begin
        tmp_var = qu.pop_front();
        $display("Index of Asoc Array for b==6 is %0d", tmp_var);
    end

    //type-3:with multiple conditions
    qu = assoc_array.find_index with (item.a == 2 && item.b == 6);
    count = qu.size();
    for(int i = 0; i < count; i++)begin
        tmp_var = qu.pop_front();
        $display("Index of Asoc Array for a == 2,b==6 is %0d", tmp_var);
    end

end

endmodule

上記のコードでは、クラス パケットには int 型の 2 つの変数と、メンバーの変数値を出力する表示メソッドが含まれています。assoc_array モジュールでは、パケット タイプの連想配列が定義されます。パケット クラス ハンドル、および int 型 count、tmp_var、queue qu を宣言します。
次に、パケット クラスの 3 つのインスタンスが作成され、連想配列要素に割り当てられます。最後に、配列の検索メソッドを呼び出します。これにより、キューが返されます。次に、キューの Pop_front() メソッドを使用して、キュー内の要素を取り出して出力します。実行結果は以下の通りです。
ここに画像の説明を挿入します

配列反復子

配列内の要素またはインデックスを検索できますが、個別にのみ検索できます。イテレータ iterator を使用すると、配列内の要素またはインデックスを同時に処理できます。イテレータを簡単に理解すると、with 内の項目として考えることができます。

array_1.find with (item == item.index)

値がインデックスである配列要素を返します。

array_2.find with (item > item.index)

値がインデックスより大きい配列要素を返します。

module fixedsize_array;

    //declaration of array's
    int array_1[6]  ;
    int array_2[6]  ;
    int temp_qu[$]  ;
    int temp_cnt    ;
    int temp_value  ;

    initial begin
        //array initialization
        array_1 = '{
    
    10,20,2,40,67,5};
        array_2 = '{
    
    80,4,2,40,67,5};

        //type-1
        temp_qu = array_1.find with (item == item.index);
        temp_cnt = temp_qu.size();
        $display("Index and Elements are same for %0d index's", temp_cnt);

        for(int i = 0; i < temp_cnt; i++)begin
            temp_value = temp_qu.pop_front();
            $display("\tsame for value %0d", temp_value);
        end

        //type-2
        temp_qu = array_1.find with (item > item.index);
        temp_cnt = temp_qu.size();
        $display("Index and Elements satisfied for %0d index's", temp_cnt);

        for(int i = 0; i < temp_cnt; i++)begin
            temp_value = temp_qu.pop_front();
            $display("\t for value %0d", temp_value);
        end
    end

endmodule

上記の例では、item はデータ要素の値を参照し、item.index は要素のインデックスで、find はデータ要素を返します。item==item.index で値とインデックスが等しい要素を検索し、item>item.index でインデックスより値が大きい要素を検索します。要素と要素インデックスの両方が使用されていることがわかります。実行結果は以下の通りです。
ここに画像の説明を挿入します

配列スライス

配列の場合、スライス スライスは配列内の連続した要素であり、パーツ選択スライスは要素を選択する連続したビットです。

bit [31:0] data;
bit [07:0] byte[4];
 
byte[0] = data[07:0];
byte[1] = data[15:8];
byte[2] = data[23:16];
byte[3] = data[31:24];

上に示したように、パート選択は Verilog に似ており、要素に対する別の操作であるインデックス選択を通じて 8 ビットをバイトに割り当てます。
スライスは、複数の配列要素をより小さな配列に分割するもので、これは配列に対する操作です。

  bit [31:0] packet_type_A [7:0]; //array of 8 elements of width 32bit
  bit [31:0] packet_type_B [1:0]; //array of 2 elements of width 32bit
 
  packet_type_B = packet_type_A[5:4]; //assigning 2 elements of array packet_type_A  to packet_type_B

systemverilog では、よりフリップフロップなチップ選択方法が提供されています。
+:表記

byte = data[j += k]

ここで、j は開始ビットを表し、k は合計桁数を表します。byte = data[0 +: 8] など。byte = data[7:0] と同等です。
最大のインデックスを指定し、-: を使用して他のインデックスを設定することもできます。j は依然として開始インデックスであり、k in -: は引き続き k ビットを意味しますが、他のインデックスは開始インデックスから減分されます。data[7-:8] が data[7:0] と同等の場合
ここに画像の説明を挿入します
、ここでの j は変数にすることができ、k は定数でなければならないことに注意してください。

おすすめ

転載: blog.csdn.net/weixin_45614076/article/details/126504032