”
intel HLS コンパイラを試してみる11(mm_slave その1)”の続き。
前回は、4つのAvalon Slave インターフェース(最初の1つはAvalon Master だが)を i++ でコンパイルした。今回は、ModelSimでシミュレーション波形を見ていこう。
今回も intel HLS のチュートリアルの F:\intelFPGA_lite\17.1\hls\examples\tutorials\interfaces\mm_slave を題材にする。
part_1_basic_component最初に、part_1_basic_component.cpp のシミュレーション波形を見ていく。
シミュレーション波形全体を下に貼る。

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

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 でデータを書いていく。

part_1_basic_component.cpp では、同じアドレスの int 型の変数から 4 バイト・レーン読んで、4 バイト・レーン書いているので、C の記述とハードウェア化された動作が違っているが、最適化のためだろう?と思う。
最後に done の波形を貼っておく。
part_2_slave_component次に、part_2_slave_component.cpp のシミュレーション波形を見てみよう。
最初に全体の波形を示す。

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 の一部を引用する。

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

最初に、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 になっている。
part_3_slave_register_argumentspart_3_slave_register_arguments.cpp のシミュレーション波形を見ていく。
シミュレーション波形全体を下に貼る。 x と N が無くなっている。これはレジスタにマップされている。swp_int_end_csr.h の一部を引用する。

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

レジスタマップを示す。 x と N がレジスタにマップされているのが分かる。swp_int_end_csr.h の一部を引用する。

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 になっている。
part_4_slave_mem_args最後のpart_4_slave_mem_args.cpp のシミュレーション波形を見ていこう。
シミュレーション波形全体を示す。他のと違っている。すべてスレーブだからか?

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

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

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

最初は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 だった。

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

Read もバイトごとにRead している。バイト・イネーブルが1バイトごとにイネーブルになっていく。
これで、4 つのパターンの特徴が分かった。自分で一番使うとしたら、part_3_slave_register_arguments だろうかな?
- 2017年11月23日 08:15 |
- intel HLS
-
| トラックバック:0
-
| コメント:0