一、前言

FPGA设计中,经常会用到位宽转换,这个很常见的设计。这不,今天就用vivado hls来设计这个模块,看看效果如何。

二、小位宽转大位宽头文件设计

#ifndef _TOP_H_
#define _TOP_H_

#include"hls_video.h"

#include"ap_int.h"


typedef unsigned char uchar;

#define i_w 64
#define o_w 32
#define io_w i_w+o_w


void hls_stream_conv_top(hls::stream<ap_uint<i_w> >& input, hls::stream<ap_uint<o_w> >& output,ap_uint<32> len);

#endif
 

二、小位宽转大位宽TB设计

#include "iostream"

using namespace std;

using namespace cv;

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

    hls::stream<ap_uint<i_w> > input;
    hls::stream<ap_uint<o_w> > output;
    ap_uint<32> len = 100;
    ap_uint<64> tmp = 0;
    ap_uint<32> rslt = 0;

    for(ap_uint<32> i =0;i<100;i++){
        tmp(7,0)   = i(7,0);
        tmp(15,8)  = i(7,0);
        tmp(23,16) = i(7,0);
        tmp(31,24) = i(7,0);
        tmp(39,32) = i(7,0);
        tmp(47,40) = i(7,0);
        tmp(55,48) = i(7,0);
        tmp(63,56) = i(7,0);


        input << tmp;
    }

    hls_stream_conv_top(input, output, len);

   for(ap_uint<32> j =0;j<200;j++){
       output >> rslt;
       std::cout <<std::hex << rslt <<std::endl;
       }


return 0;

}
 

三、小位宽转大位宽的核心顶层设计

#include "top.h"

void hls_stream_conv_top(hls::stream<ap_uint<i_w> >& input, hls::stream<ap_uint<o_w> >& output,ap_uint<32> len)
{
#pragma HLS INTERFACE ap_ctrl_hs port=return
#pragma HLS INTERFACE axis register both port=output
#pragma HLS INTERFACE axis register both port=input
#pragma HLS INTERFACE ap_stable port=len
    ap_uint<32>   sum_width_tmp = 0;
    ap_int<32>    remain_width = 0;
    ap_int<32>    remain_width2 = 0;
    ap_int<io_w>  data_buff = 0;
    ap_int<io_w>  data_buff_tmp = 0;

    for(ap_uint<32> i=0;i<len;i++){
#pragma HLS PIPELINE
        ap_uint<i_w> data_tmp = 0;
        if(sum_width_tmp < o_w )
          data_tmp = input.read();//block read input stream

        ap_uint<32> sum_width = sum_width_tmp + i_w;//累计的输入数据数据位宽
        remain_width  = sum_width - o_w;//存够一个输出数据后,输出数据,还剩的位宽数
        remain_width2 = sum_width - 2*o_w;


        data_buff_tmp = data_buff | (ap_uint<io_w>)(data_tmp)<<sum_width_tmp;

        ap_uint<io_w> data_buff_tmp1 = data_buff_tmp;

        if(remain_width2>=0){
            output << data_buff_tmp(o_w-1,0);//输出一次数据
            output << data_buff_tmp(2*o_w-1,o_w);//输出一次数据
            data_buff = data_buff_tmp1 >> (2*o_w);
            sum_width_tmp = remain_width2;//还剩位宽
        }
        else if(remain_width>=0){//足够输出数据位宽,将输出一个数据
            output << data_buff_tmp(o_w-1,0);//输出一次数据
            data_buff = data_buff_tmp1 >> o_w;
            sum_width_tmp = remain_width;//还剩位宽
        }
        else{//输入数据位宽不满足输出数据位宽要求,继续输入有效数据
            data_buff = data_buff_tmp;
            sum_width_tmp = sum_width;//还剩位宽
        }


    }


}

四、仿真与验证

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐