はじめに
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 にて生成されるコードをみてみます。