- 追加された行はこのように表示されます。
- 削除された行は
このように表示されます。
!AFU/PAC 開発メモ その1
まずはHello Worldに毛をはやす.
サンプルの hw/samples/hello_afu/build_synth は,PAC上にレジスタを作って
SWから読み書きする,というもの.
レジスタを一つ追加してみる.
logic [63:0] scratch_reg;
logic [63:0] scratch_reg2; // 追加
を用意して,レジスタ番号は32bit単位っぽいので,64bit幅の場合,2飛びで指定.
always_ff @(posedge clk)
begin
if (reset)
begin
scratch_reg <= '0;
scratch_reg2 <= '0;
end
else
begin
// set the registers on MMIO write request
// these are user-defined AFU registers at offset 0x40.
if (cp2af_sRxPort.c0.mmioWrValid == 1)
begin
case (mmioHdr.address)
16'h0020: scratch_reg <= cp2af_sRxPort.c0.data[63:0];
16'h0022: scratch_reg2 <= cp2af_sRxPort.c0.data[63:0] * 2; // 追加
endcase
end
end
end
SWから書いた値を2倍して保存してみることに.
読む方にも対応したアドレスへのアクセスを追加
//
// Handle MMIO reads.
//
always_ff @(posedge clk)
begin
if (reset)
begin
af2cp_sTxPort.c1.hdr <= '0;
af2cp_sTxPort.c1.valid <= '0;
af2cp_sTxPort.c0.hdr <= '0;
af2cp_sTxPort.c0.valid <= '0;
af2cp_sTxPort.c2.hdr <= '0;
af2cp_sTxPort.c2.mmioRdValid <= '0;
end
else
begin
...略...
// Scratch Register. Return the last value written
// to this MMIO address.
16'h0020: af2cp_sTxPort.c2.data <= scratch_reg;
16'h0022: af2cp_sTxPort.c2.data <= scratch_reg2; // 追加
...略...
end
end
Quartus上で合成だけ通しておきたければ,Quartusプロジェクトのbuild_synth/build/dcp.qpfを開いて,
afu_synthをベースにafu_devを作って Analysis&Synthesis だけ実行しておくといい.
gbs作るときには,特にファイルを追加したりしているわけではないので,build_synthの下で,
% ${OPAE_PLATFORM_ROOT}/bin/run.sh
とすれば,それでいい.
ソフトウェアからのアクセスではバイト単位でアドレス指定する必要があって,
/* test */
res = fpgaWriteMMIO64(afc_handle, 0, 0x88, 0xa5a5a5a5a5a5a5a);
res = fpgaReadMMIO64(afc_handle, 0, 0x88, &data);
printf("[test] Reading Scratch Register (Byte Offset=%08x) = %08lx\n", 0x88, data);
res = fpgaReadMMIO64(afc_handle, 0, 0x80, &data);
printf("[test] Reading Scratch Register (Byte Offset=%08x) = %08lx\n", 0x80, data);
こんな感じに.
* 0x88(PAC上では0x22)に0xa5a5a5a5a5a5a5aを書いて読むと,2倍された 0x14b4b4b4b4b4b4b4 が読める
* 0x88にデータを書いても,0x80には影響ない
ことが確認できてOK.