本文主要是介绍Vitis HLS 学习笔记--添加 RTL 黑盒函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
1. 简介
2. 用法详解
2.1 需要的文件
2.1.1 RTL 函数签名
2.1.2 黑盒 JSON 描述文件
2.1.3 RTL IP 文件
2.2 操作步骤
3. 总结
1. 简介
Vitis HLS 工具可以将现有的 Verilog RTL IP(即硬件描述语言编写的模块)集成到 C/C++ HLS 项目中。通过这种方式,Vitis HLS 能够将 RTL 代码与 C/C++ 代码一起综合,形成最终的硬件设计。
RTL 黑盒允许设计者在 HLS 设计中的特定区域(如顺序区域、流水线区域或数据流区域)内使用 Verilog 或 VHDL 编写的 RTL IP。这样做的好处是可以重用现有的硬件模块,同时利用 HLS 的优势来加速整个设计和开发过程。
简单的说,如果你有一个用 Verilog 编写的性能优化好的 IP,可以将其作为黑盒插入到 HLS 项目中,而不需要将其重新用 C/C++ 实现。这样可以节省时间,并确保硬件设计的高效性和可靠性。
2. 用法详解
2.1 需要的文件
2.1.1 RTL 函数签名
RTL 代码的 C 语言函数签名,是指用于代表RTL模块的C函数的声明。这个签名定义了函数的名称、输入参数和返回类型,这样C代码就可以调用它,就像调用任何其他C函数一样。这个签名通常放在一个头文件(.h)中,以便在整个项目中使用。
#include "ap_int.h"//--------------------------------------------------------
//RTL 代码的 C 语言函数签名
//--------------------------------------------------------
void rtl_model(ap_int<10> a1, ap_int<10> a2, ap_int<10> a3, ap_int<10> a4,ap_int<10> b1, ap_int<10> b2, ap_int<10> b3, ap_int<10> b4,ap_int<10>& z1, ap_int<10>& z2, ap_int<10>& z3, ap_int<10>& z4);//--------------------------------------------------------
void example(ap_int<10> a1, ap_int<10> a2, ap_int<10> a3, ap_int<10> a4,ap_int<10> b1, ap_int<10> b2, ap_int<10> b3, ap_int<10> b4,ap_int<10>& sigma) {ap_int<10> tmp1, tmp2, tmp3, tmp4;rtl_model(a1, a2, a3, a4, b1, b2, b3, b4, tmp1, tmp2, tmp3, tmp4);sigma = tmp1 + tmp2 + tmp3 + tmp4;
}
2.1.2 黑盒 JSON 描述文件
{
"c_function_name" : "rtl_model",
"rtl_top_module_name" : "rtl_model",
"c_files" : [{ "c_file" : "rtl_model.cpp","cflag" : ""}],
"rtl_files" : ["rtl_model.v"],
"c_parameters" : [{"c_name" : "a1","c_port_direction" : "in","rtl_ports" : {"data_read_in" : "a1"}},{"c_name" : "a2","c_port_direction" : "in","rtl_ports" : {"data_read_in" : "a2"}},{"c_name" : "a3","c_port_direction" : "in","rtl_ports" : {"data_read_in" : "a3"}},{"c_name" : "a4","c_port_direction" : "in","rtl_ports" : {"data_read_in" : "a4"}},{"c_name" : "b1","c_port_direction" : "in","rtl_ports" : {"data_read_in" : "b1"}},{"c_name" : "b2","c_port_direction" : "in","rtl_ports" : {"data_read_in" : "b2"}},{"c_name" : "b3","c_port_direction" : "in","rtl_ports" : {"data_read_in" : "b3"}},{"c_name" : "b4","c_port_direction" : "in","rtl_ports" : {"data_read_in" : "b4"}},{"c_name" : "z1","c_port_direction" : "out","rtl_ports" : {"data_write_out" : "z1","data_write_valid" : "z1_ap_vld"}},{"c_name" : "z2","c_port_direction" : "out","rtl_ports" : {"data_write_out" : "z2","data_write_valid" : "z2_ap_vld"}},{"c_name" : "z3","c_port_direction" : "out","rtl_ports" : {"data_write_out" : "z3","data_write_valid" : "z3_ap_vld"}},{"c_name" : "z4","c_port_direction" : "out","rtl_ports" : {"data_write_out" : "z4","data_write_valid" : "z4_ap_vld"}}],
"rtl_common_signal" : {"module_clock" : "ap_clk","module_reset" : "ap_rst","module_clock_enable" : "ap_ce","ap_ctrl_chain_protocol_idle" : "ap_idle","ap_ctrl_chain_protocol_start" : "ap_start","ap_ctrl_chain_protocol_ready" : "ap_ready","ap_ctrl_chain_protocol_done" : "ap_done","ap_ctrl_chain_protocol_continue" : "ap_continue"},
"rtl_performance" : {"latency" : "2","II" : "1"},
"rtl_resource_usage" : {"FF" : "0","LUT" : "0","BRAM" : "0","URAM" : "0","DSP" : "1"}
}
2.1.3 RTL IP 文件
`timescale 100ps/100ps(* use_dsp = "simd" *)
(* dont_touch = "1" *)
module rtl_model (input ap_clk, ap_rst, ap_ce, ap_start, ap_continue,input [9:0] a1, a2, a3, a4, b1, b2, b3, b4,output ap_idle, ap_done, ap_ready,output z1_ap_vld, z2_ap_vld, z3_ap_vld, z4_ap_vld,output reg [9:0] z1, z2, z3, z4);wire ce = ap_ce;reg [9:0] areg1, areg2, areg3, areg4;reg [9:0] breg1, breg2, breg3, breg4;reg dly1, dly2;always @ (posedge ap_clk)if (ap_rst)beginz1 <= 0;z2 <= 0;z3 <= 0;z4 <= 0;areg1 <= 0;areg2 <= 0;areg3 <= 0;areg4 <= 0;breg1 <= 0;breg2 <= 0;breg3 <= 0;breg4 <= 0;dly1 <= 0;dly2 <= 0; endelse if (ce)beginz1 <= areg1 + breg1;z2 <= areg2 + breg2;z3 <= areg3 + breg3;z4 <= areg4 + breg4;areg1 <= a1;areg2 <= a2;areg3 <= a3;areg4 <= a4;breg1 <= b1;breg2 <= b2;breg3 <= b3;breg4 <= b4;dly1 <= ap_start;dly2 <= dly1; endassign z1_ap_vld = dly2;assign z2_ap_vld = dly2;assign z3_ap_vld = dly2;assign z4_ap_vld = dly2;assign ap_ready = dly2;assign ap_done = dly2;assign ap_idle = ~ap_start;endmodule // rtl_model
2.2 使用 RTL 黑盒向导
整体步骤和常规的 Vitis HLS 步骤一致,特殊点在于多了一个 JSON 文件需要配置:
- 从顶层函数内或者从 Vitis HLS 工程的子函数内调用 C 语言函数签名。
- 在 Vitis HLS IDE 中使用“Add Files”(添加文件),将黑盒 JSON 描述文件添加到 HLS 工程中。
- 运行 Vitis HLS 设计文件照常进行仿真、综合和协同仿真。
使用 RTL 黑盒向导操作步骤:
在导航到工程中,打开 RTL 黑盒向导:
3. 总结
Vitis HLS 的引入为硬件设计师提供了一种灵活高效的设计途径,通过允许 RTL 黑盒的使用,设计师可以在不牺牲性能的前提下,重用现有的硬件模块,同时利用 HLS 的高层次抽象和快速迭代能力来加速设计和开发过程。这种方法既节省了将硬件模块重新用 C/C++ 实现的时间,也保持了设计的高效性和可靠性。通过简化操作步骤和提供直观的工具,如 RTL Blackbox Wizard,Vitis HLS 降低了硬件设计的复杂性,使得开发者能够更加专注于创新和优化。
这篇关于Vitis HLS 学习笔记--添加 RTL 黑盒函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!