SystemVerilog の struct packed は Verilator にどうマッピングされるか

この記事は TSG Advent Calendar 2023 2 日目のエントリです。 昨日の記事は Verilator + GoogleTest で SystemVerilog のモジュールを単体テストする - マグマグ (起動音) でした。

小ネタですが、検索しても出てこなかったのでメモとして残しておきます。 たとえば、以下のような SystemVerilog の struct packed があったとします。

typedef struct packed {
    logic a;
    logic b;
    logic [3:0] c;
} my_struct_t;

SystemVerilog の構造体は定義した順に下位ビットからメンバが並びますが、 C++ の構造体は定義した順に上位ビットからメンバが並びます。

したがって、Verilator で C++ ライブラリに変換するときには、逆順にメンバを並べる必要があります。 以下のようなビットフィールドのメンバが定義された構造体を用いれば、 SystemVerilog の struct packed と同じメモリマッピングになります。

struct my_struct_t {
    uint32_t c : 4;
    uint32_t b : 1;
    uint32_t a : 1;
} __attribute__((packed));

あとは適宜 std::memcpy などを使って、SystemVerilog の struct packed と C++ の構造体の間でデータをコピーすれば OK です。