lite对多个寄存器配置应用-vivado hls设计第四十二例

  • 时间:2025-12-02 21:57 作者: 来源: 阅读:5
  • 扫一扫,手机访问
摘要:一、顶层设计 #include "top.h" #include "hls_opencv.h" #include "iostream" using namespace std; using namespace cv; int main (int argc, char** argv) { int len = 100; ap_uint<32> tmp; ap_uint<

一、顶层设计

#include "top.h"

#include "hls_opencv.h"

#include "iostream"

using namespace std;

using namespace cv;

int main (int argc, char** argv)
{

int len = 100;
ap_uint<32> tmp;
ap_uint<32> tmp1;
ap_uint<32> tmp2;


hls::stream<ap_uint<32> > src_axi;
hls::stream<ap_uint<32> > dst_axi;
hls::stream<ap_uint<32> > dst_axi1;


for(int i=0;i<100;i++){//row
    tmp1(7,0)     = i;
    tmp1(15,8)  = i;
    tmp1(23,16) = i;
    tmp1(31,24) = i;


    src_axi << tmp1;//write

    //std::cout<<std::hex <<tmp1<<std::endl;
}

hls_video_scaler_top(src_axi,dst_axi,5,20);

for(int i=0;i<100;i++){//
    //tmp1 = dst_axi.read() ;
    dst_axi  >> tmp1;
    std::cout<<std::hex <<tmp1<<std::endl;
}

//waitKey(0);

return 0;

}

二、核心代码设计

void hls_video_scaler_top
(
    hls::stream<ap_uint<32> >& src_strm,//8*4
    hls::stream<ap_uint<32> >& dst_strm,//8*4
    ap_uint<16> width,
    ap_uint<16> height
)
{
#pragma HLS INTERFACE s_axilite port=width bundle=para_cfg
#pragma HLS INTERFACE s_axilite port=height bundle=para_cfg
#pragma HLS DATAFLOW
//#pragma HLS INTERFACE ap_hs port=trans_en
#pragma HLS INTERFACE ap_ctrl_hs port=return
#pragma HLS INTERFACE axis  port=src_strm
#pragma HLS INTERFACE axis  port=dst_strm
//#pragma HLS INTERFACE ap_stable port=width
//#pragma HLS INTERFACE ap_stable port=height

    ap_uint<32> clock1_data;

    //-----------------------------------------------------------------------------------------------------------------
    for(ap_uint<16> i=0;i<height;i++){
#pragma HLS LOOP_FLATTEN off
        for(ap_uint<16> j=0;j< (width);j++){
#pragma HLS pipeline II=1
                clock1_data = src_strm.read();

                dst_strm << clock1_data;
               

        }//col

    }//row
}

三、rtl仿真

width和height总共两个寄存器,消耗10个clock才准备好,然后拉高ap_start,才进行数据流传输。

当把width和height两个寄存器通过axilite写的时候,是串行写的,消耗周期比较多,只有width和height都准备好,才进行数据的操作。

四、lite和stream并行传输

如何将axilite配置的寄存器和hls::stream传输保证是并行的,而不是串行的呢?如何实现呢??

                                                        图-1

lite参数存入RAM中,然后通过stream传递出来,需要注意的是fifo的位宽最大为1024,也就是32个32bit位宽的寄存器,也就是一个stream数据流最多一次传输32个寄存器,如果寄存器很多的话,就需要把axilite分成多个数据流给下游模块,这个问题是用户设计需要注意的!!!

这样设计的好处是,相比较下图的优点很多

                                                        图-2

图-2利用axilite配置参数,需要参数配置好了,才能启动stream的开启,否则数据不稳定,会对流程有影响,比如参数有宽和高,这个参数必须稳定才行。所以上述axilite寄存器配置是影响stream流程的开启时间的,这个会消耗时钟周期;但是图-1的架构,很好的解决了这个问题,能够保证寄存器配置和stream数据读写是独立的,因为将axilite参数存入到RAM中去,当数据流模块需要参数的时候从axilite转stream模块中去取一次参数就行了。

需要注意的是,高位宽的stream流会占用很大的block ram资源,这个用户要注意!当然可以将位宽设置小点,然后分多次读stream,这样就是需要时钟周期多一点,但是这样的效率远远高于一堆寄存器直接用axilite配置。也就是你自己要找到一个资源和时钟周期的平衡即可!

五、多次调用顶层设计的TB设计

#include "top.h"

#include "hls_opencv.h"

#include "iostream"

using namespace std;

using namespace cv;

int main (int argc, char** argv)
{

int len = 100;
ap_uint<32> tmp;
ap_uint<32> tmp1;
ap_uint<32> tmp2;


hls::stream<ap_uint<32> > src_axi;
hls::stream<ap_uint<32> > dst_axi;
hls::stream<ap_uint<32> > dst_axi1;


ap_uint<16> width = 5;
ap_uint<16> height = 10;

for(int ii=0;ii<2;ii++){
    if(ii==0){
        width = 5;
        height = 20;
    }
    else{
        width = 10;
        height = 10;
    }

    for(int i=0;i<100;i++){//row
        tmp1(7,0)     = i;
        tmp1(15,8)  = i;
        tmp1(23,16) = i;
        tmp1(31,24) = i;


        src_axi << tmp1;//write

        //std::cout<<std::hex <<tmp1<<std::endl;
    }

    hls_video_scaler_top(src_axi,dst_axi,width,height);

    for(int j=0;j<100;j++){//
        //tmp1 = dst_axi.read() ;
        dst_axi  >> tmp1;
        std::cout<<std::hex <<tmp1<<std::endl;
    }
}


//waitKey(0);

return 0;

}

六、多次调用顶层设计的核心代码

void hls_video_scaler_top
(
    hls::stream<ap_uint<32> >& src_strm,//8*4
    hls::stream<ap_uint<32> >& dst_strm,//8*4
    ap_uint<16> width,
    ap_uint<16> height
)
{
#pragma HLS INTERFACE s_axilite port=width bundle=para_cfg
#pragma HLS INTERFACE s_axilite port=height bundle=para_cfg
//#pragma HLS DATAFLOW
//#pragma HLS INTERFACE ap_hs port=trans_en
#pragma HLS INTERFACE ap_ctrl_hs port=return
#pragma HLS INTERFACE axis  port=src_strm
#pragma HLS INTERFACE axis  port=dst_strm
//#pragma HLS INTERFACE ap_stable port=width
//#pragma HLS INTERFACE ap_stable port=height

    ap_uint<32> clock1_data;

    //-----------------------------------------------------------------------------------------------------------------
    for(ap_uint<16> i=0;i<height;i++){
#pragma HLS LOOP_FLATTEN off
        for(ap_uint<16> j=0;j< (width);j++){
#pragma HLS pipeline II=1
                clock1_data = src_strm.read();

                dst_strm << clock1_data;

        }//col

    }//row

}

七、代码综合和rtl仿真

1.上述仿真rtl可以看出ap_start拉高了两次,表示这个模块开启了两次图像数据传输。

2.axilite寄存器的配置都是在ap_start拉低期间配置的,也就是一轮图像传输完成后再开始更新lite寄存器。

  • 全部评论(0)
手机二维码手机访问领取大礼包
返回顶部