SystemVerilog:packedとunpacked

SystemVerilogでは「packed」という予約語が追加されています。
前回の「SystemVerilog:構造体と共用体」を例に解説したいと思います。
筆者の感覚レベルですが、パック型にすることでBit操作のような記述が可能になる。
つまり、変数(構造体,共用体)a に対して a[2]=0; や a[2:0]=3'b000;みたいな書き方が出来るということなのかな。

では、まず「packed」を宣言せずにBit操作するような書き方だとどうなるか?
・ソースコードはこちら
 1 module testbench();
 2   //構造体のデータ型
 3   typedef struct {
 4     int          i;
 5     int unsigned j;
 6     bit[3:0]     k; 
 7   } st_data_t;
 8 
 9   st_data_t st_data;
10 
11   initial begin
12     st_data.i    = -10;     $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
13     st_data.j    = 10;      $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
14     st_data.k    = 4'b0101; $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
15     // ↓Bit操作のような書き方もしたい。「st_data.k」にアクセス
16     st_data[3:0] = 7;       $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
17     $finish();
18   end
19 
20 endmodule

実行結果はこちら。

コンパイル時にエラーがでます。この場合はアンパック型の構造体だったからです。

続いて、パック型の構造体にするとどうなるか。
ソースコードはこちら
 1 module testbench();
 2   //構造体のデータ型(packed)
 3   typedef struct packed {
 4     int          i;
 5     int unsigned j;
 6     bit[3:0]     k; 
 7   } st_data_t;
 8 
 9   st_data_t st_data;
10 
11   initial begin
12     st_data.i    = -10;     $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
13     st_data.j    = 10;      $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
14     st_data.k    = 4'b0101; $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
15     // ↓Bit操作のような書き方もしたい。「st_data.k」にアクセス
16     st_data[3:0] = 7;       $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
17     $finish();
18   end
19 
20 endmodule

シミュレーション結果はこちら

コンパイルエラーもなく、値が書き込めているのがわかると思います。

では、共用体の場合はどうか。
共用体は一つの値を管理します。
なので、パック型共用体内にある変数のBit幅を合わせる必要があります。
合わせないと以下のようなコンパイルエラーがでます。


今回はint/int unsignedにbit幅を合わせるための修正をしました。
 1 module testbench();
 2   //共用体のデータ型(packed)
 3   typedef union packed {
 4     int          i;
 5     int unsigned j;
 6     bit[31:0]    k; //Bit幅を合わせる 
 7   } st_data_t;
 8 
 9   st_data_t st_data;
10 
11   initial begin
12     st_data.i    = -10;     $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
13     st_data.j    = 10;      $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
14     st_data.k    = 4'b0101; $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
15     st_data[3:0] = 7;       $display("i=%x, j=%x, k=%x", st_data.i, st_data.j, st_data.k);  
16     $finish();
17   end
18 
19 endmodule

シミュレーション結果はこちら

動作しているのが確認できるかと思います。

最後に配列記述の例を紹介して終わりです。
これらについては試してみてはいかがでしょうか。
logic[3:0][7:0] a; - これは packedになります。
logic[3:0] a[7:0]; - これは unpackedになります。
関連記事

コメントの投稿

非公開コメント

プロフィール

Kocha

Author:Kocha
なんでもチャレンジ!(^o^)/
E-mail
github:Kocha
イベントカレンダー

カレンダー
05 | 2017/06 | 07
- - - - 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 28 29 30 -
カテゴリ
OVP (4)
最新記事
最新コメント
アーカイブ
リンク
Twitter
アクセス人数