工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> VHDL

VHDLテストベンチでTEXTIOを使ってBMPビットマップ画像を読み込む

VHDLテストベンチで画像をインポートする最も簡単な方法は、BMPラスター・グラフィックス形式を使用することです。BMPファイルはWindowsでネイティブにサポートされ、圧縮なしで生のピクセル・データを公開するため、シミュレーションに最適です。

この記事では、バイナリBMPファイルを読み取り、ピクセル・データを動的メモリに格納し、VHDLのDUTに供給し、処理済み画像を新しいBMPファイルに書き戻す方法を説明します。例のDUTはグレースケール変換を実行しますが、この技術はあらゆるピクセル単位処理モジュールに適用可能です。

TEXTIOシリーズの一部:

なぜBMPがVHDLに最適な形式か

JPEGとPNGはウェブで普及していますが、両方とも圧縮を採用しています。JPEGは非可逆、PNGは可逆圧縮ですが、どちらもテストベンチがピクセル・データに直接アクセスする際に複雑さを追加します。一方、BMPは画像データを非圧縮ラスター・グラフィックスとして格納するため、各ピクセルが生のRGBバイトで表現されます。これにより、VHDLでの展開コードが不要になり、決定論的なシミュレーション時間が保証されます。

PhotoshopやGIMPなどの一般的な画像エディターは、内部的に画像をラスター・データとしてメモリにロードします。VHDLでは、ソース画像を手動で(またはスクリプト経由で)BMPに変換するのが最も直接的なアプローチです。

BMPファイルの準備

Windowsペイントを使用して一貫したファイル・レイアウトを確保します:

  1. 画像を開く。
  2. ファイル > 名前を付けて保存を選択。
  3. 24ビット ビットマップ (*.bmp; *.dib)を選択して保存。

この方法では、ファイル・ヘッダーは常にRGB24ピクセル形式の54バイトBITMAPINFOHEADERバリアントになります。以下の表は読み取るヘッダー・フィールドを示しています。

オフセット(10進)サイズ(B)期待値(16進)説明
0242 4DIDフィールド
10454 (36 00 00 00)ピクセル配列オフセット
14440 (28 00 00 00)ヘッダー・サイズ
184読み取り値画像幅(ピクセル)
224読み取り値画像高さ(ピクセル)
26101カラー・プレーン数
28118ピクセルあたりビット数

緑色で塗られたフィールドのみが必須で、残りは整合性チェック用です。

テスト・ケース

以下は、24ビットRGB入力を受け取り、対応する輝度値をRGBにエンコードして出力する最小限のグレースケールDUTです。このモジュールは純粋な組み合わせ回路なのでクロックは不要です。

entity grayscale is port ( r_in : in std_logic_vector(7 downto 0); g_in : in std_logic_vector(7 downto 0); b_in : in std_logic_vector(7 downto 0); r_out : out std_logic_vector(7 downto 0); g_out : out std_logic_vector(7 downto 0); b_out : out std_logic_vector(7 downto 0) ); end grayscale; 

完全なプロジェクト・ソース(1000×1000ピクセルのBoeing 747 BMP含む)は、リンク先のフォームにメールアドレスを入力することでダウンロード可能です。

TEXTIOのインポート

VHDLファイルの冒頭に以下を追加:

use std.textio.all; use std.env.finish;

これらの宣言にはVHDL-2008以降が必要です。

画像格納用カスタム型

テストベンチの宣言領域で以下の型を定義:

type header_type is array (0 to 53) of character; type pixel_type is record red : std_logic_vector(7 downto 0); green : std_logic_vector(7 downto 0); blue : std_logic_vector(7 downto 0); end record; type row_type is array (integer range <>) of pixel_type; type row_pointer is access row_type; type image_type is array (integer range <>) of row_pointer; type image_pointer is access image_type;

これらの動的データ構造により、テストベンチは静的配列の制限なしに任意サイズの画像を扱えます。

DUTのインスタンス化

signal r_in, g_in, b_in : std_logic_vector(7 downto 0); signal r_out, g_out, b_out : std_logic_vector(7 downto 0); begin DUT : entity work.grayscale port map ( r_in => r_in, g_in => g_in, b_in => b_in, r_out => r_out, g_out => g_out, b_out => b_out ); 

BMPヘッダーの読み取り

プロセスは54バイトのヘッダーをheader変数にロードし、assert文で主要フィールドを検証します。このガードにより、サポートされていないファイル形式の誤用を防止します。

for i in header_type'range loop read(bmp_file, header(i)); end loop; -- 基本的な整合性チェック assert header(0) = 'B' and header(1) = 'M' report "First two bytes are not ""BM"". This is not a BMP file" severity failure; assert character'pos(header(10)) = 54 and character'pos(header(11)) = 0 and character'pos(header(12)) = 0 and character'pos(header(13)) = 0 report "Pixel array offset is not 54 bytes" severity failure; assert character'pos(header(14)) = 40 and character'pos(header(15)) = 0 and character'pos(header(16)) = 0 and character'pos(header(17)) = 0 report "DIB header size is not 40 bytes, is this a Windows BMP?" severity failure; assert character'pos(header(26)) = 1 and character'pos(header(27)) = 0 report "Color planes is not 1" severity failure; assert character'pos(header(28)) = 24 and character'pos(header(29)) = 0 report "Bits per pixel is not 24" severity failure;

検証後、画像幅と高さを抽出:

image_width := character'pos(header(18)) + character'pos(header(19)) * 2**8 + character'pos(header(20)) * 2**16 + character'pos(header(21)) * 2**24; image_height := character'pos(header(22)) + character'pos(header(23)) * 2**8 + character'pos(header(24)) * 2**16 + character'pos(header(25)) * 2**24; report "image_width: " & integer'image(image_width) & ", image_height: " & integer'image(image_height);

ピクセル・データの読み取り

各BMP行は4バイトの倍数にパディングされます。行あたりのパディングを計算し、画像用の動的格納領域を確保します。

padding := (4 - image_width*3 mod 4) mod 4; image := new image_type(0 to image_height - 1); for row_i in 0 to image_height - 1 loop row := new row_type(0 to image_width - 1); for col_i in 0 to image_width - 1 loop read(bmp_file, char); row(col_i).blue := std_logic_vector(to_unsigned(character'pos(char), 8)); read(bmp_file, char); row(col_i).green := std_logic_vector(to_unsigned(character'pos(char), 8)); read(bmp_file, char); row(col_i).red := std_logic_vector(to_unsigned(character'pos(char), 8)); end loop; for i in 1 to padding loop read(bmp_file, char); end loop; -- パディングを廃棄 image(row_i) := row; end loop;

DUTのテスト

各ピクセルをDUTに供給し、小さなデルタ・サイクル待機後、グレースケール出力を取得します。

for row_i in 0 to image_height - 1 loop row := image(row_i); for col_i in 0 to image_width - 1 loop r_in <= row(col_i).red; g_in <= row(col_i).green; b_in <= row(col_i).blue; wait for 10 ns; row(col_i).red := r_out; row(col_i).green := g_out; row(col_i).blue := b_out; end loop; end loop;

出力BMPの書き込み

まず保存したヘッダーを書き込みます。次に、必要な場所にパディングを追加しながらピクセル・データを行ごとにシリアライズ。最後に動的メモリを解放し、ファイルを閉じます。

for i in header_type'range loop write(out_file, header(i)); end loop; for row_i in 0 to image_height - 1 loop row := image(row_i); for col_i in 0 to image_width - 1 loop write(out_file, character'val(to_integer(unsigned(row(col_i).blue)))); write(out_file, character'val(to_integer(unsigned(row(col_i).green)))); write(out_file, character'val(to_integer(unsigned(row(col_i).red)))); end loop; deallocate(row); for i in 1 to padding loop write(out_file, character'val(0)); end loop; end loop; deallocate(image); file_close(bmp_file); file_close(out_file); report "Simulation done. Check ""out.bmp"" image."; finish; end process;

結果画像

生成されたout.bmpファイルは、元のBoeing 747画像のグレースケール版を示します。記事にはJPEGプレビューが表示され、完全なBMPファイルはダウンロード・フォームから入手可能です。

さらなる考慮事項

VHDL

  1. ホログラフィの謎を解明:ガボールのノーベル賞受賞発明から未来のデータストレージまで
  2. NASAラングレー研究センターが3Dカラーイメージング用先進プレノプティックカメラを発表
  3. Linuxでデジタル署名を使用してバイナリファイルの完全性を検証する方法
  4. C# usingステートメント完全ガイド:名前空間インポート、エイリアス、静的ディレクティブ
  5. C言語 ファイル入出力: fopen, fprintf, fread, fseek をマスターする
  6. C言語ヘッダーファイルの理解:種類、使い方、ベストプラクティス
  7. VHDLのTEXTIOライブラリでテキスト・ファイルからFPGAブロックRAMを初期化する
  8. VerilogファイルI/Oの完全ガイド:オープン、読み取り、書き込み、クローズ
  9. Python JSON:エンコード、デコード、ファイル処理の実践ガイド
  10. Javaファイル操作のマスター:java.ioによる作成・読み取り・書き込み・削除
  11. Java BufferedReader でファイル読み込み:実践ガイドと例