BitMapを作成する SystemVerilog

Systemverilog

はじめに

SystemVerilogでビットマップを作成します。

グレースケール(ビットの深さ8bit)、カラー(ビットの深さ24bit)両対応版です。

サンプルコード

bmp_typedef.svh

typedef用のヘッダーファイルです。

`ifndef _BMP_TYPEDEF
`define _BMP_TYPEDEF
typedef bit [7:0] BYTE;
typedef bit [15:0] WORD;
typedef bit [31:0] DWORD;

typedef struct packed {
    DWORD OffBits;
    WORD Reserved2;
    WORD Reserved1;
    DWORD Size;
    WORD Type;
} BitMapFileHeader_t;

typedef struct packed {
    DWORD ClrImportant;
    DWORD ClrUsed;
    DWORD YPixPerMeter;
    DWORD XPixPerMeter;
    DWORD SizeImage;
    DWORD Compression;
    WORD  BitCount;
    WORD  Planes;
    DWORD Height;
    DWORD Width;
    DWORD Size;
} BitMapInfoHeader_t;

typedef struct packed{
    BYTE Reserved;
    BYTE Red;
    BYTE Green;
    BYTE Blue;
} BitMapRGB_t;
`endif
bmp_pkg.svh

Packageです。

`ifndef _BMP_PKG
`define _BMP_PKG
package bmp_pkg;
    `include "bmp_typedef.svh"

    function void save(byte img[], string filename, int width, int height, bit color);
        int f;
        BitMapFileHeader_t File;
        BitMapInfoHeader_t Info;
        BitMapRGB_t rgb[256];

        File.Type = 19778;
        File.Size  = 14 + 40 + width*height;
        File.Size += color ? 0 : 1024;
        File.Reserved1 = 0;
        File.Reserved2 = 0;
        File.OffBits  = 14 + 40;
        File.OffBits += color ? 0 : 1024;

        Info.Size = 40;
        Info.Width = width;
        Info.Height = height;
        Info.Planes = 1;
        Info.BitCount = color ? 24 : 8;
        Info.Compression = 0;
        Info.SizeImage = 0;
        Info.XPixPerMeter = 0;
        Info.YPixPerMeter = 0;
        Info.ClrUsed = 0;
        Info.ClrImportant = 0;

        foreach (rgb[i]) begin
            rgb[i].Blue = i;
            rgb[i].Green = i;
            rgb[i].Red = i;
            rgb[i].Reserved = 0;
        end

        f = $fopen(filename, "wb");
        for (int i = 0; i < 14; i++)    $fwrite(f, "%c", File[i*8 +: 8]);
        for (int i = 0; i < 40; i++)    $fwrite(f, "%c", Info[i*8 +: 8]);
        if (!color) foreach (rgb[j])
            for (int i = 0; i < 4; i++) $fwrite(f, "%c", rgb[j][i*8 +: 8]);
        foreach (img[i])                $fwrite(f, "%c", img[i]);
        $fclose(f);
    endfunction
endpackage
`endif
top.sv

使い方です。

`include "bmp_pkg.svh"
module top;
    import bmp_pkg::*;

    int width = 256;
    int height = 256;

    byte img[];
    initial begin  // グレースケール画像を保存します。
        img = new[width * height];
        for (int h = 0; h < 256; h++) begin
            for (int w = 0; w < 256; w++) begin
                img[w+width*h] = w;
            end
        end
        save(img, "gray.bmp", width, height, 0);
        img.delete();
    end

    initial begin  // カラー画像を保存します。
        img = new[width * height * 3];
        for (int h = 0; h < 256; h++) begin
            for (int w = 0; w < 256; w++) begin
                for (int c = 0; c < 3; c++) begin
                    img[c+3*w+3*width*h] = w;
                end
            end
        end
        save(img, "color.bmp", width, height, 1);
        img.delete();
    end
endmodule

使い方

bmp_pkg.svh, bmp_typedef.svhがカレントディレクトリにある状態でtop.svを実行すると、gray.bmp, color.bmpが作成されます。

解説

bmp_typedef.svhではビットマップのヘッダの構造体を定義しています。

bmp_pkg.svhでは画像を保存するsave()メソッドを持ちます。引数は以下です。

save(<1byteの画素データ>, <保存するファイル名>, <画像の横幅>, <画像の縦幅>, <1でカラー画像、0でグレース画像)

まとめ

SystemVerilogでビットマップを作成しました

コメント

タイトルとURLをコピーしました