FC2カウンター FPGAの部屋 intel HLS

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

intel HLS コンパイラを試してみる12(mm_slave その2)

intel HLS コンパイラを試してみる11(mm_slave その1)”の続き。

前回は、4つのAvalon Slave インターフェース(最初の1つはAvalon Master だが)を i++ でコンパイルした。今回は、ModelSimでシミュレーション波形を見ていこう。

part_1_basic_component
最初に、part_1_basic_component.cpp のシミュレーション波形を見ていく。
シミュレーション波形全体を下に貼る。
Intel_HLS_101_171123.png

1つのRead 区間とWrite 区間は 260000 ps (260 ns) でクロックが 1000 ps なので、260 クロック分あるが、Read で見ると 2 クロックで1転送で、転送数は 130 個、ビットレーンごとに 4 回繰り返しているので、130/2 = 32.5 個だが、中途半端な数なので、たぶん32個ずつ処理していて、4クロック分は余計に必要なんだと思う。

次にStart 信号を見てみよう。
Intel_HLS_102_171123.png

Start 信号が 1 クロック分出て、その後に、Read 転送が入っているのが見える。Avalon-MM の Read 転送は”Avalon® Interface Specifications MNL-AVABUSREF 2017.05.08”の 23 ページの”Figure 7. Read and Write Transfers with Waitrequest”を見ると、read が 1 の時の最初のクロックでアドレスを認識して、次のクロックでRead データを受け取るようだ。
Read は同じアドレスを4 回 Read しているようだ。

Write は 1 クロックでWrite できるようだ。バイト・レーンの変換で、1バイトごとに書いているが、最初にバイト・レーン・イネーブルが 08 と 80 でアドレスを大きくしてデータを書いていって、次は、04 と 40 で、その次は01 と 10 で、最後に 02 と 20 でデータを書いていく。
Intel_HLS_103_171123.png

part_1_basic_component.cpp では、同じアドレスの int 型の変数から 4 バイト・レーン読んで、4 バイト・レーン書いているので、C の記述とハードウェア化された動作が違っているが、最適化のためだろう?と思う。

最後に done の波形を貼っておく。
Intel_HLS_104_171123.png

part_2_slave_component
次に、part_2_slave_component.cpp のシミュレーション波形を見てみよう。
最初に全体の波形を示す。
Intel_HLS_105_171123.png

Start 信号や busy, done, stall などの信号は無くなっている。その代わりに、avs_xra_... の信号が追加されていて、スタートを支持したり、エンドを知ることができる。

アドレスマップは、F:\intelFPGA_lite\17.1\hls\examples\tutorials\interfaces\mm_slaves\part_2_slave_component.prj\components\swp_int_end フォルダのswp_int_end_csr.h ファイルにあった。swp_int_end_csr.h を示す。
Intel_HLS_108_171123.png

最初のスタートを見てみよう。
Intel_HLS_106_171123.png

最初に、avs_xra_... の信号で、アドレスの2番地、3番地、1番地の最下位バイトに 1 を書いている。
2番地が 0x10 で、interrupt_enable[0:0] に 1 を書いて、Enable interrupt として、3番地が 0x18 で、interrupt_status is write 1 to clear なので、interrupt_status をクリアしているようだ。そして 1 番地が 0x8 で、 start[0:0] を 1 にしているようだ。

最後に、avs_xra_... の信号で、アドレスの3番地から 3 を読みだしている。これは、0x18 で、done[0:0] と interrupt_status[0:0] が共に 1 になっている。
Intel_HLS_107_171123.png

part_3_slave_register_arguments
part_3_slave_register_arguments.cpp のシミュレーション波形を見ていく。
シミュレーション波形全体を下に貼る。 x と N が無くなっている。これはレジスタにマップされている。
Intel_HLS_110_171123.png

最初の設定部分を拡大する。レジスタへの設定が表示されている。
Intel_HLS_111_171123.png

レジスタマップを示す。 x と N がレジスタにマップされているのが分かる。
Intel_HLS_109_171123.png

Avalon Slave へのWrite が見えるが、
最初は2番地で、0x10 の interrupt_enable[0:0] を 1 にしているようだ。
次の 3 番地は 0x18 で、interrupt_status[0:0] を 1 にしている。
4 番地は 0x20 で x[63:0] に 0x71b810 を書いている。
5 番地は 0x28 で、N[31:0] に 0x1000 を書いている。
1番地は 0x8 で、start[0:0] に 1 を書いて、スタートしている。

波形の最後は、、avs_xra_... の信号で、アドレスの3番地から 3 を読みだしている。これは、0x18 で、done[0:0] と interrupt_status[0:0] が共に 1 になっている。
Intel_HLS_112_171123.png

part_4_slave_mem_args
最後のpart_4_slave_mem_args.cpp のシミュレーション波形を見ていこう。
シミュレーション波形全体を示す。他のと違っている。すべてスレーブだからか?
Intel_HLS_113_171123.png

最初にスタート信号は無い。まずはスレーブなので、swp_int_end のメモリにデータをバイトごとに書いているのだろう?すべて受け身になるので、こうする必要がありそうだ。
Intel_HLS_114_171123.png

データを書いた後でスタートするようだ。スレーブ・インターフェースしかないため、自分で読むことができないので、書かれてからスタートするしかないのだと思う。
Intel_HLS_115_171123.png

アドレスマップを示す。 x はスレーブで書かれるので必要ないようだ。N だけレジスタマップされている。
Intel_HLS_117_171123.png

最初は2番地で、0x10 の interrupt_enable[0:0] を 1 にしているようだ。
次の 3 番地は 0x18 で、interrupt_status[0:0] を 1 にしている。
4 番地は 0x20 で、N[31:0] に 0x1000 を書いている。
1番地は 0x8 で、start[0:0] に 1 を書いて、スタートしている。

スタートは良いのだが、結果もマスタが読んでくる必要があるようだ。つまり、何もアクセスが無い時間はスタートして処理を行っている時間ということだ。処理時間は、4.111 us だった。
Intel_HLS_118_171123.png

スタートしてから、4.111 us 後には 3 番地、0x18 をRead すると 3 が出て、、done[0:0] と interrupt_status[0:0] が共に 1 になっているのが分かる。
Intel_HLS_116_171123.png

Read もバイトごとにRead している。バイト・イネーブルが1バイトごとにイネーブルになっていく。

これで、4 つのパターンの特徴が分かった。自分で一番使うとしたら、part_3_slave_register_arguments だろうかな?
  1. 2017年11月23日 08:15 |
  2. intel HLS
  3. | トラックバック:0
  4. | コメント:0

intel HLS コンパイラを試してみる11(mm_slave その1)

intel HLS コンパイラを試してみる10(examples\tutorials\interfaces\mm_master_testbench_operators その2)”の続き。

前回は、examples\tutorials\interfaces\mm_master_testbench_operators をやってみたが、今回は、mm_slave をやってみることにする。
mm_slave にはpart_1_basic_component.cpp、part_2_slave_component.cpp、part_3_slave_register_arguments.cpp、part_4_slave_mem_args.cpp の4つのC++ ソースファイルがある。
READMEに説明が書いてある。README の説明に従ってやってみることにする。

part_1_basic_component.cpp はintel HLS の通常の Start , busy, done などがある intel HLS のデフォルトのインターフェースになる気がする。
component void swp_int_end() の動作としては、32ビット幅のデータの8ビットごとの入れ替えで、エンディアンを変換する関数のようだ。

component void swp_int_end (int* x,
                            int N ) {


Intel_HLS_94_171121.png

part_2_slave_component.cpp は、 Avalon-MMスレーブインタフェースとして実装されるようだ。(hls_avalon_slave_component)

hls_avalon_slave_component
component void swp_int_end (int* x, 
                            int N ) {


Intel_HLS_95_171121.png

part_3_slave_register_arguments.cpp は、コンポーネントの引数をコンポーネントのAvalon-MMスレーブインタフェースのメモリマップに追加しているそうだ。コンポーネントの引数のそれぞれがスレーブレジスタとして指定されているということだ。(hls_avalon_slave_register_argument)

hls_avalon_slave_component
component void swp_int_end (hls_avalon_slave_register_argument int* x,
                            hls_avalon_slave_register_argument int N ) {


Intel_HLS_96_171121.png

part_4_slave_mem_args.cpp は、ポインタ(Avalon MM-Master)インタフェースを、M20Kを使用した整数配列を格納するスレーブ・メモリに置き換えるそうだ。x のみ hls_avalon_slave_memory_argument() が使用されている。x はAvalon-MM マスタ・インターフェースになるのかもしれない?

hls_avalon_slave_component
component void swp_int_end (hls_avalon_slave_memory_argument(BUFFER_SIZE*sizeof(int)) int* x,
                            hls_avalon_slave_register_argument int N) {


Intel_HLS_97_171121.png

build.bat を示す。14行目をArria10 からCyclone Vに変更した。
Intel_HLS_98_171121.png

build.bat を起動した。
Intel_HLS_99_171121.png

part_1_basic_component.cpp、part_2_slave_component.cpp、part_3_slave_register_arguments.cpp、part_4_slave_mem_args.cpp の4つともPASSED になった。

F:\intelFPGA_lite\17.1\hls\examples\tutorials\interfaces\mm_slaves フォルダの内容を示す。
Intel_HLS_100_171121.png

F:\intelFPGA_lite\17.1\hls\examples\tutorials\interfaces\mm_slaves\part_1_basic_component.prj\components\swp_int_end フォルダのswp_int_end_inst.v の内容の一部を示す。

swp_int_end swp_int_end_inst (
  // Interface: clock (clock end)
  .clock               ( ), // 1-bit clk input
  // Interface: reset (reset end)
  .resetn              ( ), // 1-bit reset_n input
  // Interface: call (conduit sink)
  .start               ( ), // 1-bit valid input
  .busy                ( ), // 1-bit stall output
  // Interface: return (conduit source)
  .done                ( ), // 1-bit valid output
  .stall               ( ), // 1-bit stall input
  // Interface: x (conduit sink)
  .x                   ( ), // 64-bit data input
  // Interface: N (conduit sink)
  .N                   ( ), // 32-bit data input
  // Interface: avmm_0_rw (avalon start)
  .avmm_0_rw_address   ( ), // 64-bit address output
  .avmm_0_rw_byteenable( ), // 8-bit byteenable output
  .avmm_0_rw_read      ( ), // 1-bit read output
  .avmm_0_rw_readdata  ( ), // 64-bit readdata input
  .avmm_0_rw_write     ( ), // 1-bit write output
  .avmm_0_rw_writedata ( )  // 64-bit writedata output
);


Start などのブロックレベルの信号とメモリ・インターフェースがある。

F:\intelFPGA_lite\17.1\hls\examples\tutorials\interfaces\mm_slaves\part_2_slave_component.prj\components\swp_int_end フォルダのswp_int_end_inst.v の内容の一部を示す。

swp_int_end swp_int_end_inst (
  // Interface: clock (clock end)
  .clock               ( ), // 1-bit clk input
  // Interface: reset (reset end)
  .resetn              ( ), // 1-bit reset_n input
  // Interface: irq (interrupt end)
  .done_irq            ( ), // 1-bit irq output
  // Interface: x (conduit sink)
  .x                   ( ), // 64-bit data input
  // Interface: N (conduit sink)
  .N                   ( ), // 32-bit data input
  // Interface: avmm_0_rw (avalon start)
  .avmm_0_rw_address   ( ), // 64-bit address output
  .avmm_0_rw_byteenable( ), // 8-bit byteenable output
  .avmm_0_rw_read      ( ), // 1-bit read output
  .avmm_0_rw_readdata  ( ), // 64-bit readdata input
  .avmm_0_rw_write     ( ), // 1-bit write output
  .avmm_0_rw_writedata ( ), // 64-bit writedata output
  // Interface: avs_cra (avalon end)
  .avs_cra_read        ( ), // 1-bit read input
  .avs_cra_write       ( ), // 1-bit write input
  .avs_cra_address     ( ), // 2-bit address input
  .avs_cra_writedata   ( ), // 64-bit writedata input
  .avs_cra_byteenable  ( ), // 8-bit byteenable input
  .avs_cra_readdata    ( )  // 64-bit readdata output
);


start, busy, done, stall などの信号が消えて、avs_cra_.... のAvalon Slave の信号が増えた。

F:\intelFPGA_lite\17.1\hls\examples\tutorials\interfaces\mm_slaves\part_3_slave_register_arguments.prj\components\swp_int_end フォルダのswp_int_end_inst.v の内容の一部を示す。

swp_int_end swp_int_end_inst (
  // Interface: clock (clock end)
  .clock               ( ), // 1-bit clk input
  // Interface: reset (reset end)
  .resetn              ( ), // 1-bit reset_n input
  // Interface: irq (interrupt end)
  .done_irq            ( ), // 1-bit irq output
  // Interface: avmm_0_rw (avalon start)
  .avmm_0_rw_address   ( ), // 64-bit address output
  .avmm_0_rw_byteenable( ), // 8-bit byteenable output
  .avmm_0_rw_read      ( ), // 1-bit read output
  .avmm_0_rw_readdata  ( ), // 64-bit readdata input
  .avmm_0_rw_write     ( ), // 1-bit write output
  .avmm_0_rw_writedata ( ), // 64-bit writedata output
  // Interface: avs_cra (avalon end)
  .avs_cra_read        ( ), // 1-bit read input
  .avs_cra_write       ( ), // 1-bit write input
  .avs_cra_address     ( ), // 3-bit address input
  .avs_cra_writedata   ( ), // 64-bit writedata input
  .avs_cra_byteenable  ( ), // 8-bit byteenable input
  .avs_cra_readdata    ( )  // 64-bit readdata output
);


part_2_slave_component.prj とひかくすると、x と N が消えて、.avs_cra_address が 2 bit から 3 bit になった。つまり、x と N もレジスタにマップされたようだ。

F:\intelFPGA_lite\17.1\hls\examples\tutorials\interfaces\mm_slaves\part_4_slave_mem_args.prj\components\swp_int_end フォルダのswp_int_end_inst.v の内容の一部を示す。

swp_int_end swp_int_end_inst (
  // Interface: clock (clock end)
  .clock             ( ), // 1-bit clk input
  // Interface: reset (reset end)
  .resetn            ( ), // 1-bit reset_n input
  // Interface: irq (interrupt end)
  .done_irq          ( ), // 1-bit irq output
  // Interface: avs_cra (avalon end)
  .avs_cra_read      ( ), // 1-bit read input
  .avs_cra_write     ( ), // 1-bit write input
  .avs_cra_address   ( ), // 3-bit address input
  .avs_cra_writedata ( ), // 64-bit writedata input
  .avs_cra_byteenable( ), // 8-bit byteenable input
  .avs_cra_readdata  ( ), // 64-bit readdata output
  // Interface: avs_x (avalon end)
  .avs_x_read        ( ), // 1-bit read input
  .avs_x_write       ( ), // 1-bit write input
  .avs_x_address     ( ), // 12-bit address input
  .avs_x_writedata   ( ), // 32-bit writedata input
  .avs_x_byteenable  ( ), // 4-bit byteenable input
  .avs_x_readdata    ( )  // 32-bit readdata output
);


part_3_slave_register_arguments.prj と比較すると、avmm_0_rw_.... のAvalon MM-Master インターフェースが avs_x_..... のAvalon-MM slave インターフェースに置き換えられている。
  1. 2017年11月21日 05:25 |
  2. intel HLS
  3. | トラックバック:0
  4. | コメント:0

intel HLS コンパイラを試してみる10(examples\tutorials\interfaces\mm_master_testbench_operators その2)

intel HLS コンパイラを試してみる9(examples\tutorials\interfaces\mm_master_testbench_operators)”の続き。

前回は、Avalon MM インターフェースのチュートリアルをやってみて、ModelSim で波形を観測した。今回は、レポートとQuartus Prime を動かしてコンパイルしてみた。

まずは、レポートを貼っておく。

Summary
Intel_HLS_85_171119.png

Loops analysis
Intel_HLS_86_171119.png

Area analysis of system
Intel_HLS_87_171119.png

Area analysis of source
Intel_HLS_88_171119.png

Component Viewer
Intel_HLS_89_171119.png

Component memory viewer
Intel_HLS_90_171119.png

Verification statistics Latency は min = 24, max = 89, avg = 68 だった。
Intel_HLS_91_171119.png

Quartus Prime 17.1 を立ち上げた。
F:\intelFPGA_lite\17.1\hls\examples\tutorials\interfaces\mm_master_testbench_operators\operators.prj\quartus の quartus_compile.qpf を読み込んだ。
コンパイルを実行した。
Intel_HLS_92_171119.png

Entity の quartus_compile の下の、add_x をダブルクリックして開くと、IP のシンボルを見ることができた。
Intel_HLS_93_171119.png
  1. 2017年11月19日 04:51 |
  2. intel HLS
  3. | トラックバック:0
  4. | コメント:0

intel HLS コンパイラを試してみる9(examples\tutorials\interfaces\mm_master_testbench_operators)

今回は、F:\intelFPGA_lite\17.1\hls\examples\tutorials\interfaces\mm_master_testbench_operators を試してみることにした。まだ、Avalon MM インターフェースはやっていないので、やってみることにした。

Avalon MM インターフェースについては、”Avalon® Interface Specifications MNL-AVABUSREF 2017.05.08”を参照のこと。

build.bat を書き換えた。

set "DEVICE=Arria10"

から

set "DEVICE=CycloneV"

に書き換えた。
次に、i++ のオプション -ghdl を追加した。こうするとシミュレーション結果の波形 vsim.wlf が出力される。
Intel_HLS_78_171118.png

ハードウェア化するソースコードは、F:\intelFPGA_lite\17.1\hls\examples\tutorials\interfaces\mm_master_testbench_operators\operators.cpp から引用する。

component void add_x(mm_src_t &src, mm_dst_t &dst, unsigned int x) {
*dst = *src + x;
}


src と dst はAvalon MM インターフェースになっていて、x は最初は 0x10 が入っている。

build default コマンドを実行した。
Intel_HLS_79_171118.png

operators.prj フォルダができた。
Intel_HLS_84_171118.png

その中はお馴染みのcomponents、quartus、reports、verification フォルダができていた。

F:\intelFPGA_lite\17.1\hls\examples\tutorials\interfaces\mm_master_testbench_operators\operators.prj\verification フォルダのvsim.wlf ファイルをModelSim で開いた。
Intel_HLS_80_171118.png

Avalon MM インターフェースのRead は rw_address で指定したアドレスが rw_read が 1 の時に有効になるようだ。それが上の図のピンクの四角で囲った領域だ。
Intel_HLS_81_171118.png

Read データが来るのは、その後で、 rw_readdatavalid が 1 になったときのようだ。 1 になったときにrw_readdata にデータが出力されている。
Intel_HLS_82_171118.png

Avalon MM インターフェースのWrite は rw_address にアドレスを出力して、rw_write を 1 にすると同時に、rw_writedata にデータを与えれば良いようだ。
Intel_HLS_83_171118.png

Read データと Write を見比べてみると、Read データに0x10 を加算した値が Write データになっているのが分かる。
  1. 2017年11月18日 05:48 |
  2. intel HLS
  3. | トラックバック:0
  4. | コメント:0

intel HLS コンパイラを試してみる8(image_downsampleを試す2)

intel HLS コンパイラを試してみる7(image_downsampleを試す1)”の続き。

前回は、image_downsample で build test-msvc と build test-x86-64 をやってみた。今回は、build test-fpga をやってみる。

build test-fpga コマンドを実行した。
test-fpga.exe を実行したが、実行に1時間半くらいかかってしまった。
Intel_HLS_64_171115.png

レポートを見てみよう。
Summary 当たり前だが、counter よりもリソース使用量が多い。
Intel_HLS_65_171115.png

Loops analysis 左の行をクリックすると対応するソースコードがハイライトされる。
Intel_HLS_66_171115.png

Area analysis of system こちらも左の行をクリックすると対応するソースコードがハイライトされる。
Intel_HLS_67_171115.png

Area analysis of source
Intel_HLS_68_171115.png

Component Viewer
Intel_HLS_69_171115.png

Component memory viewer
Intel_HLS_70_171115.png

Component memory viewer
Intel_HLS_71_171115.png

Verification statistics Latency は 257012 クロックだった。
Intel_HLS_77_171115.png

Quartus Prime 17.1 を立ち上げて、プロジェクトを読み込んだ。
コンパイルを行って、成功した。
Intel_HLS_72_171115.png

resize:resize_inst をダブルクリックすると、IP Parameter Editor が立ち上がった。
Intel_HLS_73_171115.png

ModelSimを立ち上げて、 intelFPGA_lite\17.1\hls\examples\image_downsample\test-fpga.prj\verification のvsim.wlf を読み込んだ。約257 us シミュレーションしている。
Intel_HLS_74_171115.png

wave ウインドウを拡大した。
Intel_HLS_75_171115.png

wave ウインドウをさらに拡大した。
original_image のready と valid はこの画面ではすべて 1 だが、resized_imag の valid は1クロックおき位に 1 と 0 を繰り返している。これは、リサイズした画面のほうが小さいからだろう。
Intel_HLS_76_171115.png
  1. 2017年11月15日 04:36 |
  2. intel HLS
  3. | トラックバック:0
  4. | コメント:0

intel HLS コンパイラのレポート

F:\intelFPGA_lite\17.1\hls\examples\counter\test-fpga.prj\reports フォルダにある report.html だが、たくさん画面があったので、貼っておきたいと思う。

まずはデフォルトのSummary 画面。
Intel_HLS_55_171114.png

View report をクリックするとメニューが出てくる。ここから見たい項目を選択する。
Loops analysis を選択した。
Intel_HLS_56_171114.png

Loops analysis
Intel_HLS_63_171114.png

Area analysis of system
Intel_HLS_57_171114.png

Area analysis of source
Intel_HLS_58_171114.png

Component Viewer。これ面白そう。
Intel_HLS_59_171114.png

コンポーネントにマウスをオーバーライドすると、情報が表示される。
Intel_HLS_60_171114.png

Component memory viewer。counter では情報が無いみたいだ。
Intel_HLS_61_171114.png

Verification statistics
Intel_HLS_62_171114.png
  1. 2017年11月14日 04:42 |
  2. intel HLS
  3. | トラックバック:0
  4. | コメント:0

intel HLS コンパイラを試してみる7(image_downsampleを試す1)

intel HLS コンパイラを試してみる6(counter.cpp のコードを変更した)”の続き。

今回から counter を終了して、次のexample の image_downsample を試してみよう。 image_downsample はbmp ファイルの縦横のサイズを小さくするアプリケーションのようだ。

image_downsample のフォルダを示す。
Intel_HLS_45_171112.png

ファイルがたくさんあるが、bmp_tools.cpp は bmp のread と write を受け持っているようだ。
resize.cpp は画像のリサイズをするようだ。ここにハードウェアになる予定の

component void resize(unsigned ratio, int rows, int cols, input_image_stream& original_image, output_image_stream& resized_image);

がある。
Intel_HLS_46_171112.png

ここでは、入出力が

input_image_stream& original_image, output_image_stream& resized_image

で行われているが、これは、resize.h で

typedef ihc::stream_in<unsigned int=""> input_image_stream;
typedef ihc::stream_out<unsigned int=""> output_image_stream;

で定義されている。
これらは、Avalon® Streaming Interface のようだ。Intel High Level Synthesis Compiler User Guide のAvalon® Streaming Interface Arguments を見ると書いてある。
Avalon® Streaming Interface は入力は、read メソッドでストリームから読めて、出力は write メソッドでストリームに書けるようだ。

resize をどこから使っているか?というと main.cpp で呼ばれている。
Intel_HLS_47_171112.png
test.bmp を読んで、downsampled.bmp にダウンサンプリングして、expected.bmp と縦横サイズを比較しているようだ。

さて、build してみよう。その前に build.bat を -march=CycloneV -ghdl に修正した。
Intel_HLS_48_171112.png

これで build test-msvc を実行した。
次に、test-msvc.exe で実行した。
Intel_HLS_49_171112.png

増えたファイルを示す。
Intel_HLS_50_171112.png

test.bmp がこれだ。
Intel_HLS_53_171112.png

downsampled.bmp がこれだ。
Intel_HLS_54_171112.png

次に、build test-x86-64 コマンドを実行した。
test-x86-64.exe を実行した。
Intel_HLS_51_171112.png

増加したファイルを示す。
Intel_HLS_52_171112.png
  1. 2017年11月13日 04:57 |
  2. intel HLS
  3. | トラックバック:0
  4. | コメント:0
»