块级接口综合类型
- 在 Vitis HLS(High-Level Synthesis)中,块级接口类型用于指定模块的控制信号和通信方式,从而影响硬件实现时的控制逻辑、时序以及数据传输方式。Vitis HLS 使用以下接口类型
ap_ctrl_none,ap_ctrl_hs,ap_ctrl_chain 和s_axilite来指定 RTL IP 是否使用模块级握手信号实现。

- 注:默认情况下,block-level interface protocol 被添加到 design中。且块级接口的端口格式为ap_ctrl_hs。

块级:可以在函数或函数返回上指定块级 I/O 协议
- 如果 C/C++ 代码未返回值,您仍然可以在函数返回时指定块级 I/O 协议。如果 C/C++ 代码使用函数返回,则 Vitis HLS 会为返回值创建一个输出端口 ap_return。

ap_ctrl_none(No Control)
-
ap_ctrl_none是一种不带握手信号的控制方式,通常用于不需要显式同步控制信号的设计场景。模块之间的数据流通常是基于时序控制的,在这种模式下,控制信号的依赖关系相对较少或不存在。 -
适用场景:无需复杂控制信号,设计中可能只是简单的模块调用。
-
工作原理:不涉及复杂的握手或数据同步信号,控制信号可能是基于时钟的触发,或者是一次性数据传输。
代码效果
// LED控制函数
void hlsv1(ap_uint<1> &led) {
#pragma HLS INTERFACE ap_ctrl_none port=return
}
⇓ \Downarrow ⇓
`timescale 1 ns / 1 ps
(* CORE_GENERATION_INFO="hlsv1_hlsv1,hls_ip_2020_2,{HLS_INPUT_TYPE=cxx,HLS_INPUT_FLOAT=0,HLS_INPUT_FIXED=0,HLS_INPUT_PART=xc7z010-clg400-1,HLS_INPUT_CLOCK=10.000000,HLS_INPUT_ARCH=others,HLS_SYN_CLOCK=0.000000,HLS_SYN_LAT=0,HLS_SYN_TPT=none,HLS_SYN_MEM=0,HLS_SYN_DSP=0,HLS_SYN_FF=0,HLS_SYN_LUT=0,HLS_VERSION=2020_2}" *)
module hlsv1 (
led
);
input [511:0] led;
endmodule //hlsv1
ap_ctrl_hs (Handshaking Control)
-
ap_ctrl_hs模式是基于握手信号的控制方式,通常用于数据流的处理。在这种模式下,模块会通过握手信号来实现数据的同步传输。它是最常见的流式数据处理方式,特别适用于流水线设计和数据流控制。 -
握手信号:
- 控制块何时可以开始处理数据 (ap_start)
- 指示模块是空闲,非处理数据阶段 (ap_idle)
- 指示准备好接受新输入 (ap_ready)
- 模块已完成操作 (ap_done)

-
使用场景:适用于需要数据同步或流水线控制的设计。图像处理、音频信号处理等流式数据处理任务。例如,一个模块的输出端如果准备好给下游模块传输数据时,它会通过
valid信号通知下游模块;下游模块通过ready信号确认可以接受数据。
代码效果
// LED控制函数
void hlsv1(ap_uint<1> &led) {
#pragma HLS INTERFACE ap_ctrl_hs port=return
}
⇓ \Downarrow ⇓
`timescale 1 ns / 1 ps
(* CORE_GENERATION_INFO="hlsv1_hlsv1,hls_ip_2020_2,{HLS_INPUT_TYPE=cxx,HLS_INPUT_FLOAT=0,HLS_INPUT_FIXED=0,HLS_INPUT_PART=xc7z010-clg400-1,HLS_INPUT_CLOCK=10.000000,HLS_INPUT_ARCH=others,HLS_SYN_CLOCK=0.000000,HLS_SYN_LAT=0,HLS_SYN_TPT=none,HLS_SYN_MEM=0,HLS_SYN_DSP=0,HLS_SYN_FF=0,HLS_SYN_LUT=0,HLS_VERSION=2020_2}" *)
module hlsv1 (
ap_start,
ap_done,
ap_idle,
ap_ready,
led
);
input ap_start;
output ap_done;
output ap_idle;
output ap_ready;
input [511:0] led;
assign ap_done = ap_start;
assign ap_idle = 1'b1;
assign ap_ready = ap_start;
endmodule //hlsv1
ap_ctrl_chain
-
ap_ctrl_chain模式(流水线内核)允许多个模块形成一个链式结构,每个模块的控制信号通过链式传递。这意味着每个模块的执行控制由前一个模块的信号控制,模块间的同步是通过级联握手实现的。 -
使用场景:适用于多个模块按顺序依次执行,且每个模块的执行依赖于前一个模块的状态。这种模式通常用于复杂的流水线设计中,各模块的数据依赖性较强时使用。
代码效果
// LED控制函数
void hlsv1(ap_uint<1> &led) {
#pragma HLS INTERFACE ap_ctrl_chain port=return
}
⇓ \Downarrow ⇓
`timescale 1 ns / 1 ps
(* CORE_GENERATION_INFO="hlsv1_hlsv1,hls_ip_2020_2,{HLS_INPUT_TYPE=cxx,HLS_INPUT_FLOAT=0,HLS_INPUT_FIXED=0,HLS_INPUT_PART=xc7z010-clg400-1,HLS_INPUT_CLOCK=10.000000,HLS_INPUT_ARCH=others,HLS_SYN_CLOCK=0.000000,HLS_SYN_LAT=0,HLS_SYN_TPT=none,HLS_SYN_MEM=0,HLS_SYN_DSP=0,HLS_SYN_FF=2,HLS_SYN_LUT=11,HLS_VERSION=2020_2}" *)
module hlsv1 (
ap_clk,
ap_rst,
ap_start,
ap_done,
ap_continue,
ap_idle,
ap_ready,
led
);
parameter ap_ST_fsm_state1 = 1'd1;
input ap_clk;
input ap_rst;
input ap_start;
output ap_done;
input ap_continue;
output ap_idle;
output ap_ready;
input [511:0] led;
reg ap_done;
reg ap_idle;
reg ap_ready;
reg ap_done_reg;
(* fsm_encoding = "none" *) reg [0:0] ap_CS_fsm;
wire ap_CS_fsm_state1;
reg ap_block_state1;
reg [0:0] ap_NS_fsm;
wire ap_ce_reg;
// power-on initialization
initial begin
#0 ap_done_reg = 1'b0;
#0 ap_CS_fsm = 1'd1;
end
always @ (posedge ap_clk) begin
if (ap_rst == 1'b1) begin
ap_CS_fsm <= ap_ST_fsm_state1;
end else begin
ap_CS_fsm <= ap_NS_fsm;
end
end
always @ (posedge ap_clk) begin
if (ap_rst == 1'b1) begin
ap_done_reg <= 1'b0;
end else begin
if ((ap_continue == 1'b1)) begin
ap_done_reg <= 1'b0;
end else if ((~((ap_start == 1'b0) | (ap_done_reg == 1'b1)) & (1'b1 == ap_CS_fsm_state1))) begin
ap_done_reg <= 1'b1;
end
end
end
always @ (*) begin
if ((~((ap_start == 1'b0) | (ap_done_reg == 1'b1)) & (1'b1 == ap_CS_fsm_state1))) begin
ap_done = 1'b1;
end else begin
ap_done = ap_done_reg;
end
end
always @ (*) begin
if (((ap_start == 1'b0) & (1'b1 == ap_CS_fsm_state1))) begin
ap_idle = 1'b1;
end else begin
ap_idle = 1'b0;
end
end
always @ (*) begin
if ((~((ap_start == 1'b0) | (ap_done_reg == 1'b1)) & (1'b1 == ap_CS_fsm_state1))) begin
ap_ready = 1'b1;
end else begin
ap_ready = 1'b0;
end
end
always @ (*) begin
case (ap_CS_fsm)
ap_ST_fsm_state1 : begin
ap_NS_fsm = ap_ST_fsm_state1;
end
default : begin
ap_NS_fsm = 'bx;
end
endcase
end
assign ap_CS_fsm_state1 = ap_CS_fsm[32'd0];
always @ (*) begin
ap_block_state1 = ((ap_start == 1'b0) | (ap_done_reg == 1'b1));
end
endmodule //hlsv1
s_axilite
-
s_axilite是一种专门用于与 AXI Lite 接口交互的控制信号模式。AXI Lite 是一种较为简单的通信协议,常用于低带宽、高效的控制与状态寄存器读写。 -
使用场景:
s_axilite表示该函数/模块将通过 AXI Lite 总线进行通信,适用于与控制寄存器交互的设计,例如读取和写入配置寄存器、状态寄存器等。通常用于系统的控制接口,与外部处理器或主控系统通信。
典型用法:
#pragma HLS INTERFACE s_axilite port=control
这条指令将模块的 control 端口映射为 AXI Lite 接口,通常用于控制寄存器或简单的指令交互。
例子:
void example_function(int *control) {
// 这个函数的控制信号将通过 AXI Lite 接口传输
*control = 10;
}
代码效果
void hlsv1(ap_uint<1> &led) {
#pragma HLS INTERFACE s_axilite port=return
}
⇓ \Downarrow ⇓
`timescale 1 ns / 1 ps
(* CORE_GENERATION_INFO="hlsv1_hlsv1,hls_ip_2020_2,{HLS_INPUT_TYPE=cxx,HLS_INPUT_FLOAT=0,HLS_INPUT_FIXED=0,HLS_INPUT_PART=xc7z010-clg400-1,HLS_INPUT_CLOCK=10.000000,HLS_INPUT_ARCH=others,HLS_SYN_CLOCK=0.000000,HLS_SYN_LAT=0,HLS_SYN_TPT=none,HLS_SYN_MEM=0,HLS_SYN_DSP=0,HLS_SYN_FF=36,HLS_SYN_LUT=40,HLS_VERSION=2020_2}" *)
module hlsv1 (
led,
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,
interrupt
);
parameter C_S_AXI_CONTROL_DATA_WIDTH = 32;
parameter C_S_AXI_CONTROL_ADDR_WIDTH = 4;
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 [511:0] led;
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;
output interrupt;
wire ap_start;
wire ap_done;
wire ap_idle;
wire ap_ready;
reg ap_rst_n_inv;
hlsv1_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),
.ap_start(ap_start),
.interrupt(interrupt),
.ap_ready(ap_ready),
.ap_done(ap_done),
.ap_idle(ap_idle)
);
assign ap_done = ap_start;
assign ap_idle = 1'b1;
assign ap_ready = ap_start;
always @ (*) begin
ap_rst_n_inv = ~ap_rst_n;
end
endmodule //hlsv1
- 此外还有一个
hlsv1_control_s_axi模块

1686

被折叠的 条评论
为什么被折叠?



