​​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)
       begin
          z1    <= 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;     
       end
     else if (ce)
       begin
          z1    <= 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;          
       end

   assign 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 黑盒向导

RTL 黑盒向导用于将 C/C++ 文件“加密”成 RTL 语言。

整体步骤和常规的 Vitis HLS 步骤一致,特殊点在于多了一个 JSON 文件需要配置:

  • 从顶层函数内或者从 Vitis HLS 工程的子函数内调用 C 语言函数签名。
  • 在 Vitis HLS IDE 中使用“Add Files”(添加文件),将黑盒 JSON 描述文件添加到 HLS 工程中。
  • 运行 Vitis HLS 设计文件照常进行仿真、综合和协同仿真。

使用 RTL 黑盒向导操作步骤:

在导航到工程中,打开 RTL 黑盒向导:

//--------------------------------------------------------
//rtl_model.cpp
//--------------------------------------------------------

#include "example.h"
//--------------------------------------------------------
void rtl_model(data_t a1, data_t a2, data_t a3, data_t a4, data_t b1, data_t b2,
               data_t b3, data_t b4, data_t& z1, data_t& z2, data_t& z3,
               data_t& z4) {
#pragma HLS inline off
    z1 = a1 + b1;
    z2 = a2 + b2;
    z3 = a3 + b3;
    z4 = a4 + b4;
}

添加 rtl_model.cpp 到对话框中,需要选中其中 rtl_model 函数,可得以下内容:

参数解释:

  • C Function:即,C 语言函数;用于指定 RTL IP 的 C 语言函数名称。
  • C Argument Name:即,C 语言实参名称;用于指定函数实参的名称。这些名称应与 IP 上的端口相关。
  • C Argument Type:即,C 语言实参类型;用于指定用于每个实参的数据类型。
  • C Port Direction:即,C 语言端口方向;用于指定实参的端口方向,对应于 IP 中的端口。
  • RAM Type:即,RAM 类型;用于指定在接口处使用的 RAM 类型。
  • RTL Group Configuration:即,RTL 组配置;用于指定对应的 RTL 信号名称。

上述对话框中,RTL Group Configuration 一列,已经全部设置完毕,但是GUI界面并未显示:

 

3. 总结

Vitis HLS 工具通过集成 Verilog RTL IP 到 C/C++ HLS 项目中,简化了硬件设计过程。RTL 黑盒技术允许设计者在特定区域内使用已有的 Verilog 或 VHDL 编写的 RTL 模块,从而重用优化好的硬件模块,避免重新实现,提高设计效率和可靠性。使用 Vitis HLS 时,设计者需要编写 RTL 函数签名、创建黑盒 JSON 描述文件并包含 RTL IP 文件。在 Vitis HLS 中添加这些文件后,运行仿真和综合步骤即可完成集成。此外,通过 RTL 黑盒向导,可以简化 C 函数与 RTL 信号的映射过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值