Vivado HLS之海明窗实现

本文指导如何使用HLS在Vivado环境中创建海明窗,包括工程建立、原理介绍、源程序分析及IP导出过程。通过具体代码和测试流程,详细解释了海明窗的实现与验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vivado HLS之海明窗实现

说明:

环境:win7 64   vivado 2014.1
开发板:zedboard version d    xc7z020clg484-1
目标:使用HLS创建一个海明窗,并对其源程序、HLS优化等进行分析。

说明:文本在参考官网资料的基础上整理而成。

声明:本文中所有的源码、工程文件在“我的资源”中可以找到,如果没有请联系作者本人。转载请注明出处。

正文:

本文将分为以下步骤:

1. 使用HLS建一个工程,添加源文件,进行功能测试

2. 海明窗原理介绍和源程序分析

3. 导出IP

4. 总结

 

1. 使用HLS建一个工程,添加源文件,进行功能测试

1)建立HLS工程。可以选择GUI的方式进行创建,详见ug871;本文选择tcl的方式。

运行Vivado HLS 2014.1 Command Prompt,使用cd命令切换到工程目录(即包含“我的资源”中“run_hls.tcl”的目录,也可以自己重新创建)。

打开后,可以使用dir命令查看是否包含此文件。

键入:vivado_hls -f run_hls.tcl

此时会自动创建一个HLS工程并出现GUI界面。如果没有出现,

键入:vivado_hls p hamming_window_prj即可

2)此时可以查看源文件(hamming_window.cpp)和testbench(hamming_window_test.cpp)文件,还可以看到out.gold.dat文件,此文件为标准的输出结果,用于对比验证。

注意,hamming_window.cpp中的函数名hamming_window即为将要生成的IP的名称,必须相同

3)选择run c Simulation进行逻辑验证。此步骤可以验证程序的语法、功能等问题。但是调试功能不强,因此建议最好先在外面验证好代码的正确性,再在HLS中进行操作。

验证后,出现下图,说明验证成功。如果失败,可能是没有指定器件,可在solution settingSynthesis 里面进行设置。


2. 海明窗原理介绍和源程序分析

4)海明窗原理介绍

广义余弦窗:

汉宁窗、海明窗和布莱克曼窗,都可以用一种通用的形式表示,这就是广义余弦窗。这些窗都是广义余弦窗的特例,汉宁窗又被称为余弦平方窗或升余弦窗,海明窗又被称为改进的升余弦窗,而布莱克曼窗又被称为二阶升余弦窗。采用这些窗可以有效地降低旁瓣的高度,但是同时会增加主瓣的宽度。

这些窗都是频率为0、2π/(N1)和4π/(N1)的余弦曲线的合成,其中N为窗的长度。通常采用下面的命令来生成这些窗:

ind=(0:N-1)'*2*pi/(N-1)

window=A-B*cos(ind)+C*cos(2*ind)

其中,A、B、C适用于自己定义的常数。根据它们取值的不同,可以形成不同的窗函数:

  汉宁窗A=0.5,B=0.5,C=0;

  海明窗A=0.54,B=0.54,C=0;

  布莱克曼窗A=0.5,B=0.5,C=0.08;


5hamming_window.cpp程序分析

hamming_window.cpp

#include "hamming_window.h" // Provides default WINDOW_LEN if not user defined

// Translation module function prototypes:
static void hamming_rom_init(in_data_t rom_array[]);

// Function definitions:
void hamming_window(out_data_t outdata[WINDOW_LEN], in_data_t indata[WINDOW_LEN])
{
   static in_data_t window_coeff[WINDOW_LEN];
   unsigned i;

   // In order to ensure that 'window_coeff' is inferred and properly
   // initialized as a ROM, it is recommended that the array initialization
   // be done in a sub-function with global (wrt this source file) scope.
   hamming_rom_init(window_coeff);

   for (i = 0; i < WINDOW_LEN; i++)
   {
#pragma HLS UNROLL

      outdata[i] = (out_data_t)window_coeff[i] * (out_data_t)indata[i];
   }
}

// This initialization function will be optimized away during high level
// sythesis (HLS), resulting in the underlying memory being inferred as a ROM
// by RTL synthesis.
static void hamming_rom_init(in_data_t rom_array[WINDOW_LEN])
{
   int i;
   for (i = 0; i < WINDOW_LEN; i++)
   {
#pragma HLS PIPELINE

      float real_val = 0.54f -
         0.46f * cos(2.0f * M_PI * i / (float)(WINDOW_LEN - 1));
      rom_array[i] = (in_data_t)(WIN_COEFF_SCALE * real_val);
   }
}


hamming_window.h

#ifndef HAMMING_WINDOW_H_
#define HAMMING_WINDOW_H_

#include <cmath>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;

#ifndef M_PI
#define M_PI           3.14159265358979323846
#endif

// If WINDOW_LEN is not defined by the user, define a default value
#ifndef WINDOW_LEN
#define WINDOW_LEN 256
#endif
// If WIN_COEFF_FRACBITS not defined by user, set a default value
#ifndef WIN_COEFF_FRACBITS
#define WIN_COEFF_FRACBITS (14)
#endif
// Set the scale factor for the window coefficients
#define WIN_COEFF_SCALE ((float)(1 << WIN_COEFF_FRACBITS))

// This function applies an Hamming window function to the 'indata' buffer,
// returning the windowed data in 'outdata'.  The coefficients are 16-bit
// scaled integer, which may be interpreted as a signed fixed point format,
// with WIN_COEFF_FRACBITS bits after the binary point.

//typedef int16_t		in_data_t;
//typedef int32_t		out_data_t;
#include "ap_int.h"
typedef ap_int<16>		in_data_t;
typedef ap_int<32>		out_data_t;

void hamming_window(out_data_t outdata[], in_data_t indata[]);

#endif // HAMMING_WINDOW_H_ not defined


6hamming_window.cpp程序分析

testbench用于测试hamming_window模块的正确性。本例选取的600个采样点进行测试,数据为:从0到+75,再到-75,再到+75,再到-75,以此类推,间隔为1.把fir的结果和一个标准结果文件out.gold.dat进行比较,如果相同,说明程序正确。

#include<stdio.h>
#include"hamming_window.h"
int main(int argc,char*argv[])
{
in_data_t test_data[WINDOW_LEN];
out_data_t hw_result[WINDOW_LEN], sw_result[WINDOW_LEN];
int i;
unsigned err_cnt =0, check_dots =0;
for(i =0; i < WINDOW_LEN; i++){
// Generate a test pattern for input to DUT
      test_data[i]=(in_data_t)((32767.0*(double)((i %16)-8)/8.0)+0.5);
// Calculate the coefficient value for this index
in_data_t coeff_val =(in_data_t)(WIN_COEFF_SCALE *(0.54-
0.46* cos(2.0* M_PI * i /(double)(WINDOW_LEN -1))));
// Generate array of expected values -- n.b. explicit casts to avoid
// integer promotion issues
      sw_result[i]=(out_data_t)test_data[i]*(out_data_t)coeff_val;
}
// Call the DUT
   printf("Running DUT...");
   hamming_window(hw_result, test_data);
   printf("done.\n");
// Check the results returned by DUT against expected values
   printf("Testing DUT results");
for(i =0; i < WINDOW_LEN; i++){
if(hw_result[i]!= sw_result[i]){
         err_cnt++;
         check_dots =0;
         cout <<
         cout <<"\n!!! ERROR at i ="<< i <<"- expected:"<<  sw_result[i]<<"got:"<< hw_result[i]<< endl;
}else{// indicate progress on console
if(check_dots ==0)
            printf("\n");
                printf(".");
if(++check_dots ==64)
            check_dots =0;
}
}
   printf("\n");
// Print final status message
if(err_cnt){
      printf("!!! TEST FAILED - %d errors detected !!!\n", err_cnt);
}else
      printf("*** Test Passed ***\n");
// Only return 0 on success
return err_cnt;
}


3. 导出IP

选择export RTL,导出格式选择IP Catalog。


4. 总结.

使用HLS设计了海明窗的IP。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值