はじめに
Xilinx Vitis の中を調べるのその16。
下記のように、multi_in1 と multi_in0 を ap_hsに、multi_out を s_axilite にした時に生成されるRTLコードをみていきます。
また、multi_in0 と multi_in1 を s_axilite にした時に生成されるRTLコードもみてみます。
#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 ap_hs register port=multi_in1 #pragma HLS INTERFACE ap_hs register port=multi_in0 *multi_out = multi_in0 * multi_in1; }
生成されたRTL
生成されたRTLのインターフェース部分です。
- ap_xxx は、そのまま
- multi_in0/multi_in1 は、ap_ackap_/vld
- multi_out は、s_axi_control_XXX
になりました。
module multi_apuint ( ap_clk, ap_rst_n, ap_start, ap_done, ap_idle, ap_ready, multi_in1_ap_vld, multi_in0_ap_vld, multi_in0, multi_in0_ap_ack, multi_in1, multi_in1_ap_ack, 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 ); parameter ap_ST_fsm_pp0_stage0 = 1'd1; parameter C_S_AXI_CONTROL_DATA_WIDTH = 32; parameter C_S_AXI_CONTROL_ADDR_WIDTH = 5; 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_clk; input ap_rst_n; input ap_start; output ap_done; output ap_idle; output ap_ready; input multi_in1_ap_vld; input multi_in0_ap_vld; input [7:0] multi_in0; output multi_in0_ap_ack; input [7:0] multi_in1; output multi_in1_ap_ack; 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;
内部回路では、
- multi_in0 : multi_apuint_regslice_forward
- multi_in1 : multi_apuint_regslice_forward
- 本体 : multi_apuint_mul_8ns_8ns_16_1_1
- multi_out : multi_apuint_control_s_axi
になりました。
これは、multi_in0/multi_in1/multi_out が ap_hs の時の
内部回路では、
- multi_in0 : multi_apuint_regslice_forward
- multi_in1 : multi_apuint_regslice_forward
- 本体 : multi_apuint_mul_8ns_8ns_16_1_1
- multi_out : multi_apuint_regslice_forward
に対して、出力の multi_out の部分が s_axi になっただけです。
multi_in0 と multi_in1 を s_axilite にした時に生成されるRTLコード
下記のように、multi_in0 と multi_in1 を s_axilite、multi_out を ap_hs にした時に生成されるRTLコードもみてみます。
#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 ap_hs_register 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のインターフェース部分です。 - ap_xxx は、そのまま - multi_in0/multi_in1 は、s_axi_control_XXX - multi_out は、ap_ackap_/vld になりました。
module multi_apuint ( ap_start, ap_done, ap_idle, ap_ready, multi_out, multi_out_ap_vld, 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 = 5; 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; output [15:0] multi_out; output multi_out_ap_vld; 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;
内部回路では、 - multi_in0 : multi_apuint_control_s_axi - multi_in1 : multi_apuint_control_s_axi - 本体 : multi_apuint_mul_8ns_8ns_16_1_1 - multi_out : multi_apuint_regslice_forward になりました。 # おわりに multi_apuint.cpp の multi_in0/multi_in1/multi_out の INTERFACE を ap_hs と s_axilite に変更して Vitis にて RTL を生成すると、計算部の実態である「multi_apuint_mul_8ns_8ns_16_1_1」の入力部と出力部に ap_hs / s_axilite に対応するRTLコードが生成されることがわかりました。 次回は、INTERFACE に m_axi を指定した時にどうなるかをみてみます。