AWS EC2 F1インスタンスについて何となくわかってきたので、もう少し自分のデザインを使ったりだとか、カスタムデザインをF1に載せたりしてみたい。
F1インスタンスのハンズオンセミナーの時はSDAccelを使ったC/C++を使ったチュートリアルだったのだが、やはりまずは自分のVerilogデザインをコンパイルして、F1インスタンス上で動かせたら格好いいよね。
というわけで、SDAccelを使わないF1インスタンスの構築フローとしてAWS HDKを使ったフローを勉強してみる。
HDKはgithub上に公開されている。
このなかで、HDKのGetting Startedの章があるので、これを動かしていきたい。
HDKの使用条件
これはREADMEを読んで知ったのだが、このフローを流すためには、Vivado SDxが必要らしい。そんなのあったかな?
っていうか、個人で使っているようなフリーのVivadoではおそらく論理合成は出来なくて、ちゃんとVivado SDxを購入するか、結局はAWS EC2上のサーバで論理合成は実施しないといけないということらしい。これはちょっと面倒だなあ...
Vivado v2017.1_sdx (64-bit) Vivado v2017.1_sdxop (64-bit) Vivado v2017.1_sdx_AR70350 (64-bit)
というわけで、F1インスタンスを立ち上げて、フロントエンドサーバ上で作業を進めていく。
AWS HDKのダウンロードと実行
普通にスクリプトを実行していくだけだ。
$ export AWS_FPGA_REPO_DIR=/home/centos/src/project_data/aws-fpga $ git clone https://github.com/aws/aws-fpga.git $AWS_FPGA_REPO_DIR $ cd $AWS_FPGA_REPO_DIR $ source hdk_setup.sh ... Copying files to /home/centos/aws-fpga/hdk/common/verif/models/ddr4_model Copying files to /home/centos/aws-fpga/hdk/common/verif/models/ddr4_rdimm_wrapper patching ddr4_rank.sv file INFO: DDR4 model build passed. INFO: ATTENTION: Don't forget to set the CL_DIR variable for the directory of your Custom Logic. INFO: Downloading the AR703530 patch. INFO: Extracting the AR703530 patch. Archive: AR703530_SDx_patch.zip creating: /home/centos/aws-fpga/patches/AR703530/vivado/ creating: /home/centos/aws-fpga/patches/AR703530/vivado/data/ extracting: /home/centos/aws-fpga/patches/AR703530/vivado/data/version.dat creating: /home/centos/aws-fpga/patches/AR703530/vivado/lib/ creating: /home/centos/aws-fpga/patches/AR703530/vivado/lib/lnx64.o/ inflating: /home/centos/aws-fpga/patches/AR703530/vivado/lib/lnx64.o/librdi_timing.so creating: /home/centos/aws-fpga/patches/AR703530/vivado/patch_readme/ extracting: /home/centos/aws-fpga/patches/AR703530/vivado/patch_readme/README_AR70350.txt INFO: AWS HDK setup PASSED.
$ cd $HDK_DIR/cl/examples/cl_hello_world # you can change cl_hello_world to any other example $ export CL_DIR=$(pwd)
次に、論理合成を実行してみる。
$ vivado -mode batch # Verify Vivado is installed. $ cd $CL_DIR/build/scripts $ ./aws_build_dcp_from_cl.sh
直ぐにコマンドプロンプトが戻ってきたので、何だこりゃと思ったのだが、どうもバックグラウンドで実行されているらしい。 しかも数時間かかるとのこと。こりゃ、面倒くさいな。。。
cl_hello_world の中身
cl_hello_world.sv
というファイルがあるので見てみた。普通にSystemVerilogのモジュールだ。
AXIのレジスタスライスなどが定義されていたり、Hello Worldのレジスタが定義されている。
こうやって制御するのか。もうちょっとかみ砕いていきたい。
/home/centos/aws-fpga/hdk/cl/examples/cl_hello_world/design/cl_hello_world.sv
module cl_hello_world ( `include "cl_ports.vh" // Fixed port definition ); `include "cl_common_defines.vh" // CL Defines for all examples `include "cl_id_defines.vh" // Defines for ID0 and ID1 (PCI ID's) `include "cl_hello_world_defines.vh" // CL Defines for cl_hello_world ... //------------------------------------------------- // Hello World Register //------------------------------------------------- // When read it, returns the byte-flipped value. always_ff @(posedge clk_main_a0) if (!rst_main_n_sync) begin // Reset hello_world_q[31:0] <= 32'h0000_0000; end else if (wready & (wr_addr == `HELLO_WORLD_REG_ADDR)) begin hello_world_q[31:0] <= wdata[31:0]; end else begin // Hold Value hello_world_q[31:0] <= hello_world_q[31:0]; end assign hello_world_q_byte_swapped[31:0] = {hello_world_q[7:0], hello_world_q[15:8], hello_world_q[23:16], hello_world_q[31:24]}; //------------------------------------------------- // Virtual LED Register //------------------------------------------------- // Flop/synchronize interface signals always_ff @(posedge clk_main_a0) if (!rst_main_n_sync) begin // Reset sh_cl_status_vdip_q[15:0] <= 16'h0000; sh_cl_status_vdip_q2[15:0] <= 16'h0000; cl_sh_status_vled[15:0] <= 16'h0000; end else begin sh_cl_status_vdip_q[15:0] <= sh_cl_status_vdip[15:0]; sh_cl_status_vdip_q2[15:0] <= sh_cl_status_vdip_q[15:0]; cl_sh_status_vled[15:0] <= pre_cl_sh_status_vled[15:0]; end // The register contains 16 read-only bits corresponding to 16 LED's. // For this example, the virtual LED register shadows the hello_world // register. // The same LED values can be read from the CL to Shell interface // by using the linux FPGA tool: $ fpga-get-virtual-led -S 0 always_ff @(posedge clk_main_a0) if (!rst_main_n_sync) begin // Reset vled_q[15:0] <= 16'h0000; end else begin vled_q[15:0] <= hello_world_q[15:0]; end // The Virtual LED outputs will be masked with the Virtual DIP switches. assign pre_cl_sh_status_vled[15:0] = vled_q[15:0] & sh_cl_status_vdip_q2[15:0];