10
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

FPGAオンボードメモリのデバッグ ~テストパターン生成/表示画面のキャプチャ~

Last updated at Posted at 2022-12-12

1. はじめに

今年もやってきましたIntel Advent Calendar
12月13日投稿予定なので、13日に時間取って書けばいいやと高を括っていましたが、ふと当日の朝公開されることに気付き、土日に慌てて書いています(汗)

本稿では、FPGAボードに搭載されているDDRメモリをMATLABの機能を使ってデバッグする方法についてご紹介します。

ここでは例としてモニターディスプレイのパターンジェネレータの表示データを読み書きする内容となっていますが、この機能を利用すると、PC上で作成したデータをFPGAから出力したり、逆に何からの処理を行った結果をDDRメモリから吸い上げてデバッグするのに利用できます。

2. 使用ボード Intel DE10-Nano

本稿で使用したボードはIntel DE10-Nanoです。特にボードに依存したことは行なっていないので、他のボードでも同様に動作すると思います。

image.png

このボードはセンサー類が搭載されたドーターボードとセットになったIntel FPGA Cloud Connectivity Kitのマザーボードとなっています。
Intel FPGA Cloud Connectivity Kitはこのあたりの記事が参考になると思います。

このボード、仕事絡みでお借りしているものを、ずっと借りっぱなしになっておりまして、すいませんTさん・・・この場を借りてお詫び申し上げますm(_ _)m

3. AXI Managerの設定

オンボードメモリへのアクセスはMATLAB/HDL VerifierAXI Managerという機能を使用して行います。

AXI Managerは、FPGAに組み込むIPコアが提供されており、これを組み込んでFPGAを実装すると、PCからJTAGやEthernetでレジスタやメモリにアクセスできるようになるという機能です。

レジスタアクセス機能を使ってFPGAボードを制御する記事は、以前こちらに投稿しました。

今回はオンボードのDDRメモリにアクセスしてRead/Writeを行なっています。

まずMATLAB上で、AXI Manager IPファイルの保存場所を確認します。

>> setupAXIManagerForQuartus
The Quartus project was not specified. You can manually add C:\ProgramData\MATLAB\SupportPackages\R2022b\toolbox\hdlverifier\
supportpackages\fpgadebug_intel\+hdlverifier\+fpga\+quartus to the IP 
search path setting of your Qsys file.

Quartus > Platform Designer(Qsys)を起動し、上記パスを読み込むと、AXI ManagerのIPが見つかります。

image.png

このIPを追加して接続すると使えるようになります。

4. 既存のシステムにAXI Managerを追加

DE10-NanoのDemoファイルに含まれていた、DDR3_VIPを流用しました。

このDemoデザインでは、
Test Pattern Generator > FrameBuffer/DDR Memory > Clock Video Out
という構成で、生成したテストパターンを一旦DDRメモリでバッファリングしてから、ビデオ出力しています。

このDemoデザインのPlatform Designerを起動し、AXI ManagerのIPを追加して、DDRメモリやTest Pattern Generator IPとFrame Buffer IPのコントロールレジスタと接続します。

image.png

コントロールレジスタにも接続したのは、パターン生成のOn/Offを制御するためです。

アドレスマップを設定します。
Test Pattern GeneratorとFrame Bufferのコントロールレジスタは、それぞれ0x4000_0000, 0x5000_0000、DDRメモリは0x0000_0000に設定しました。

image.png

あとはPlatform DesignerでHDLをGenerateし、QuartusでコンパイルしたらFPGA側の準備は完了です。

5. MATLABからアクセス

SOFファイルをダウンロードしたら、MATLABから次のコマンドでAXI Managerのセットアップを行います。

>> h = aximanager('Intel') 
h = 
  AXIManagerJTAG のプロパティ:

           Vendor: 'Intel'
    JTAGCableName: 'auto'
        DataWidth: 32
        AddrWidth: 32

次にTest Pattern GeneratorとFrame Bufferのコントロールレジスタを叩き、Enableします。

>> writememory(h, 0x40000000, 1)    % Enable Test Pattern Generator 
>> writememory(h, 0x50000000, 1)    % Enable Frame Buffer

Test Pattern GeneratorをDisableし、代わりにフレームバッファにデータを書き込みます。

>> writememory(h, 0x40000000, 0)    % Disable Test Pattern Generator

% メモリから100ワードのデータを読み出し
readData = readmemory(h, 0, 100);

% メモリに100ワードの0データを書き込み
>> writememory(h, 0, zeros(1, 100, 'uint32'));

6. 実行結果

はい、こちらはTest Pattern Generatorが生成したDDRメモリのデータを読み出して、MATLABで表示した結果。
image.png

また、逆にこちらのMATLAB画像データを↓
image.png

オンボードのDDRメモリに書き込んで表示した結果↓。
image.png

7. 最後に

DDRメモリ内の画像データの並び順

画像データがDDRメモリにどのような順序で書き込まれているか確認するのに結構時間がかかりました。
備忘録として書いておきたいと思います。

Intel Video and Image Processing SuiteのAvalon Streaming Videoなどのドキュメントと、実際にデータを見て確認しました。

下図のようにB=>G=>Rの順でDDRメモリに格納されているようです。
image.png

ちなみにRGBの配列順序を間違えるとこんな表示になってしまいます。
元画像
image.png

表示画像
image.png

MATLABでの固定小数点操作

また、MATLABでRGB 8bit の画像データから 32bit のDDRメモリに格納されるデータ配列に変換する際の固定小数点操作に非常に時間がかかって困りました。当初、1枚の画像データを変換する以下のコードに71分もかかっており、とてもじゃないけど実用的に使えそうもありませんでした。

imageSize = [768, 1024];  % v, h

nt8 = numerictype(0, 8, 0);
nt32 = numerictype(0, 32, 0);

inputImageP = imresize(imread('peppers.png'), imageSize);
figure, imshow(inputImageP), shg

% RGB => BGR
inputImagePP = inputImageP(:,:,[3 2 1]);

% BGRBGRの順に並び替え 1024*768*3
serialImageP = reshape(permute(inputImagePP, [3, 2, 1]), [prod(imageSize)*3, 1, 1]);

% Pre Allocation
writeDataP = fi(zeros(1, prod(imageSize)*3/4), nt32);

tic  
for n = 0:length(serialImageP)/4-1
    writeDataP(n+1) = fi(bitconcat(...
        fi(serialImageP(n*4+4), nt8),...
        fi(serialImageP(n*4+3), nt8),...
        fi(serialImageP(n*4+2), nt8), ...
        fi(serialImageP(n*4+1), nt8)), nt32);
end
toc

これはfiaccelコマンドでプリコンパイルすることで、なんと9万倍!に超高速化して解決できました。
これに関しては別の記事「MATLABの固定小数点演算って時間かかりすぎじゃね?」「Simulinkの固定小数点演算って速くね?」 で詳しく書いています。

終わり

10
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?