はじめに
Xilinx Vitis の中を調べるのその13。
その12で終わりにしようかな?と思っていましたが、C/C++コードに対する #pragma の INTERFACE に指定する ap_hs を違うものに変えたらどうなるか?をみることにしました。
ap_hs を s_axilite に変えてみた
下記のように、ap_hs を s_axilite に変えて、VitisでRTLを生成しました。C++コードのファイル名を mult_apuint_axilite.cpp にしました。
// multi_apuint.cpp // #include <ap_int.h> // void multi_apuint(ap_uint<8> multi_in0, ap_uint<8> multi_in1, ap_uint<16> *multi_out){ #pragma HLS PIPELINE #pragma HLS INTERFACE s_axilite port=multi_out #pragma HLS INTERFACE s_axilite port=multi_in1 #pragma HLS INTERFACE s_axilite port=multi_in0 *multi_out = multi_in0 * multi_in1; }
生成されたRTLは?
solution1/syn/verilog/multi_apuint.v は、下記のようになりました。
// RTL generated by Vitis HLS - High-Level Synthesis from C, C++ and OpenCL v2022.1 (64-bit) // Version: 2022.1 // Copyright (C) Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. // // =========================================================== `timescale 1 ns / 1 ps (* CORE_GENERATION_INFO="multi_apuint_multi_apuint,hls_ip_2022_1,{HLS_INPUT_TYPE=cxx,HLS_INPUT_FLOAT=0,HLS_INPUT_FIXED=0 ,HLS_INPUT_PART=xc7z010i-clg225-1L,HLS_INPUT_CLOCK=10.000000,HLS_INPUT_ARCH=pipeline,HLS_SYN_CLOCK=6.170000,HLS_SYN_LAT= 0,HLS_SYN_TPT=1,HLS_SYN_MEM=0,HLS_SYN_DSP=0,HLS_SYN_FF=80,HLS_SYN_LUT=145,HLS_VERSION=2022_1}" *) module multi_apuint ( ap_start, ap_done, ap_idle, ap_ready, s_axi_control_AWVALID, s_axi_control_AWREADY, s_axi_control_AWADDR, s_axi_control_WVALID, s_axi_control_WREADY, s_axi_control_WDATA, s_axi_control_WSTRB, s_axi_control_ARVALID, s_axi_control_ARREADY, s_axi_control_ARADDR, s_axi_control_RVALID, s_axi_control_RREADY, s_axi_control_RDATA, s_axi_control_RRESP, s_axi_control_BVALID, s_axi_control_BREADY, s_axi_control_BRESP, ap_clk, ap_rst_n ); parameter C_S_AXI_CONTROL_DATA_WIDTH = 32; parameter C_S_AXI_CONTROL_ADDR_WIDTH = 6; parameter C_S_AXI_DATA_WIDTH = 32; parameter C_S_AXI_CONTROL_WSTRB_WIDTH = (32 / 8); parameter C_S_AXI_WSTRB_WIDTH = (32 / 8); input ap_start; output ap_done; output ap_idle; output ap_ready; input s_axi_control_AWVALID; output s_axi_control_AWREADY; input [C_S_AXI_CONTROL_ADDR_WIDTH - 1:0] s_axi_control_AWADDR; input s_axi_control_WVALID; output s_axi_control_WREADY; input [C_S_AXI_CONTROL_DATA_WIDTH - 1:0] s_axi_control_WDATA; input [C_S_AXI_CONTROL_WSTRB_WIDTH - 1:0] s_axi_control_WSTRB; input s_axi_control_ARVALID; output s_axi_control_ARREADY; input [C_S_AXI_CONTROL_ADDR_WIDTH - 1:0] s_axi_control_ARADDR; output s_axi_control_RVALID; input s_axi_control_RREADY; output [C_S_AXI_CONTROL_DATA_WIDTH - 1:0] s_axi_control_RDATA; output [1:0] s_axi_control_RRESP; output s_axi_control_BVALID; input s_axi_control_BREADY; output [1:0] s_axi_control_BRESP; input ap_clk; input ap_rst_n; ... 途中略
インターフェース部
ap_XXX 関連の信号は、変わらず。 s_axi_control_XXXXが追加され、multi_in0、multi_in1、multi_out は削除されました。
変わらない信号
ap_clk ap_rst_n ap_start ap_done ap_idle ap_ready
追加された信号
s_axi_control_AWVALID, s_axi_control_AWREADY, s_axi_control_AWADDR, s_axi_control_WVALID, s_axi_control_WREADY, s_axi_control_WDATA, s_axi_control_WSTRB, s_axi_control_ARVALID, s_axi_control_ARREADY, s_axi_control_ARADDR, s_axi_control_RVALID, s_axi_control_RREADY, s_axi_control_RDATA, s_axi_control_RRESP, s_axi_control_BVALID, s_axi_control_BREADY, s_axi_control_BRESP,
削除された信号
multi_in1_ap_vld, multi_in0_ap_vld, multi_out_ap_ack, multi_in0, multi_in0_ap_ack, multi_in1, multi_in1_ap_ack, multi_out, multi_out_ap_vld
s_axi_control_XXX <=> multi_in0/multi_in1/multi_out
s_axi_control_XXX <=> multi_in0/multi_in1/multi_out の部分は、multi_apuint_control_s_axi モジュールが行っているようです。
s_axi_control_XXX 信号から
- multi_in0 : 出力
- multi_in1 : 出力
- multi_out / multi_out_ap_vld : 入力
を作っています。
multi_apuint_control_s_axi #( .C_S_AXI_ADDR_WIDTH( C_S_AXI_CONTROL_ADDR_WIDTH ), .C_S_AXI_DATA_WIDTH( C_S_AXI_CONTROL_DATA_WIDTH )) control_s_axi_U( .AWVALID(s_axi_control_AWVALID), .AWREADY(s_axi_control_AWREADY), .AWADDR(s_axi_control_AWADDR), .WVALID(s_axi_control_WVALID), .WREADY(s_axi_control_WREADY), .WDATA(s_axi_control_WDATA), .WSTRB(s_axi_control_WSTRB), .ARVALID(s_axi_control_ARVALID), .ARREADY(s_axi_control_ARREADY), .ARADDR(s_axi_control_ARADDR), .RVALID(s_axi_control_RVALID), .RREADY(s_axi_control_RREADY), .RDATA(s_axi_control_RDATA), .RRESP(s_axi_control_RRESP), .BVALID(s_axi_control_BVALID), .BREADY(s_axi_control_BREADY), .BRESP(s_axi_control_BRESP), .ACLK(ap_clk), .ARESET(ap_rst_n_inv), .ACLK_EN(1'b1), .multi_in0(multi_in0), .multi_in1(multi_in1), .multi_out(ret_V_fu_65_p2), .multi_out_ap_vld(multi_out_ap_vld) );
multi_in0/multi_in1 への信号は、下記のコードのように、multi_apuint_mult_8ns_8ns_16_1_1 の din0/din1 に接続しています。 multi_out からの信号は、multi_apuint_mult_8ns_8ns_16_1_1 の dout に接続しています。multi_out_ap_vld 信号は、ap_start 信号が High の時、High になっています。
multi_apuint_mul_8ns_8ns_16_1_1 #( .ID( 1 ), .NUM_STAGE( 1 ), .din0_WIDTH( 8 ), .din1_WIDTH( 8 ), .dout_WIDTH( 16 )) mul_8ns_8ns_16_1_1_U1( .din0(ret_V_fu_65_p0), .din1(ret_V_fu_65_p1), .dout(ret_V_fu_65_p2) ); always @ (*) begin if ((ap_start == 1'b1)) begin multi_out_ap_vld = 1'b1; end else begin multi_out_ap_vld = 1'b0; end end assign ret_V_fu_65_p0 = ret_V_fu_65_p00; assign ret_V_fu_65_p00 = multi_in1; assign ret_V_fu_65_p1 = ret_V_fu_65_p10; assign ret_V_fu_65_p10 = multi_in0;
multi_apuint_mul_8ns_8ns_16_1_1 モジュールは、ap_hs の時に生成されたコードと同じです。
おわりに
次回は、C/RTL Simulation にて生成されるコードをみてみます。