xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器

文章目录

  • 代码分析
  • HLS
    • 仿真和综合
      • 仿真的代码内容
      • 综合报告
    • 优化
    • IP-XACT Adapter
  • Vivado工程
    • SDK

代码分析

源文件内容为

#include "fir.h" 

void fir (
  data_t *y,
  data_t x
  ) {
  const coef_t c[N+1]={
 #include "fir_coef.dat"
    };
  

  static data_t shift_reg[N];
  acc_t acc;
  int i;
  
  acc=(acc_t)shift_reg[N-1]*(acc_t)c[N];
  loop: for (i=N-1;i!=0;i--) {
    acc+=(acc_t)shift_reg[i-1]*(acc_t)c[i];
    shift_reg[i]=shift_reg[i-1];
  }
  acc+=(acc_t)x*(acc_t)c[0];
  shift_reg[0]=x;
  *y = acc>>15;
}

头文件内容为

#ifndef _FIR_H_ 
#define _FIR_H_
#include "ap_cint.h"
#define N	58
#define SAMPLES N+10 // just few more samples then number of taps
typedef short	coef_t;
typedef short	data_t;
typedef int38	acc_t;
#endif

系数文件为
xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第1张图片

函数入口为

void fir (
  data_t *y,
  data_t x
  ) 

x为输入参量,y为输入指针参数,方便外部访问计算结果。
首先读入全部的FIR系数到一个长度N+1的常量数组中。

  const coef_t c[N+1]={
 #include "fir_coef.dat"
    };

定义静态数组,这是因为FIR滤波器需要对前k项的样本数据做处理,因此需要静态数组储存过去读入的数值。

static data_t shift_reg[N];

部分的FIR滤波器内容可以考虑HLS 开发学习(一)FIR滤波器

接下来就是将寄存器数组移位

acc=(acc_t)shift_reg[N-1]*(acc_t)c[N];
  loop: for (i=N-1;i!=0;i--) {
    acc+=(acc_t)shift_reg[i-1]*(acc_t)c[i];
    shift_reg[i]=shift_reg[i-1];
  }

然后将新值插入到shift_reg的初始位置。然后让y指针的内容为acc右移15位。(为什么要右移15位呢?除以2^15??)

acc+=(acc_t)x*(acc_t)c[0];
  shift_reg[0]=x;
  *y = acc>>15;

HLS

仿真和综合

仿真的代码内容

很直接,就是输入信号是一个脉冲信号(仅在t=0的时候不为0),然后将其不断送入fir滤波器

  int i;
  for (i=0;i<SAMPLES;i++) {
	  if(i==0)
		  signal = 0x8000;
	  else
		  signal = 0;
	  fir(&output,signal);
   	  printf("%i %d %d\n",i,(int)signal,(int)output);
//   	  fprintf(fp,"%i %d %d\n",i,signal,output);

xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第2张图片

其输出的信号波形为
xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第3张图片

综合报告

综合后可得综合报告

xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第4张图片
Estimated clock period: 8.702
Worst case latency: 174
Number of DSP48E used: 3
Number of BRAMs used: 0
Number of FFs used: 167
Number of LUTs used: 154

以及接口

xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第5张图片

优化

对源文件中的loop循环添加pipeline优化。重新综合

xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第6张图片
latency减少至62,但是硬件资源消耗提高了
xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第7张图片

这是流水线并行运算提高了运算速度,代价是更多的硬件资源消耗。

IP-XACT Adapter

在Directive里右击x,插入Directive,选择interface,进行如下配置

xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第8张图片
y也是如此

对顶层模块fir插入directive
xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第9张图片
xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第10张图片
这将包括ap_start,ap_done,ap_idle信号作为总线的适配器。

接下来重新生成设计,然后RTL导出来生成 IP-XACT adapter.

在impl文件夹中可以看到输出结果 ip, misc, verilog, vhdl.

Vivado工程

在vivado中创建一个xc7z020clg400-1的工程,通过提供的脚本进行工程初始化

xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第11张图片
相应工程文件下载

可以得到如下diagram
xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第12张图片
把刚才的fir滤波器的ip核添加进来

xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第13张图片

在diagram中添加2个fir 的ip核,分别叫fir_left和fir_right,然后自动连线

打开PL-PS中断
xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第14张图片

添加一个concat ip,将两个fir分别连到in0和in1,其输出则连接到处理系统的IRQ_F2P上

此时其地址为

xilinx暑期学校学习笔记(一)基于HLS的FIR滤波器_第15张图片

接下来创建 HDL Wrapper
然后Add source,选择constraints,将提供的约束文件添加进去,之后老规矩生成bitstream。

SDK

export hardware后launch SDK,新建板级支持包。

新建空白应用工程

添加 pynq_z2_testapp.cpynq_z2_audio.h

开发板以jtag模式启动

在line in那里插入PC的音频输出,在HP——MIC那里插入耳机

Program FPGA

让PC播放一个音频,然后在SDK中Run As > Launch On Hardware (System Debugger).

sw0为关闭时候是原始信号,打开的时候是滤波后的信号。

你可能感兴趣的:(xilinx暑期学校)