Vengineerの戯言

人生は短いけど、長いです。人生を楽しみましょう!

Xilinx Vitis の中を調べる(その16)

はじめに

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 を指定した時にどうなるかをみてみます。