ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

FPGA信号处理系列文章——Xilinx FIR IP的matlab模型的使用

2022-01-09 22:34:05  阅读:301  来源: 互联网

标签:FIR fr FPGA IP fft filter abs data size


提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

FPGA信号处理系列文章——Xilinx FIR IP的matlab模型的使用


前言

Xilinx FIR IP作为一个信号处理的IP,考虑到了如何在matlab和C模型环境下如何模拟该IP核的输入输出数据,运用Xilinx FIR IP的模型,我们无需考虑时序有关的问题就可以对输入输出进行大样本的验证,而不是通过modelsim去进行仿真。相对于matlab和C环境下的仿真效率比在modelsim上效率高千百倍,最重要的是,modelsim出来的结果和matlab或者C模型只要参数设置一致,那么输入输出会是完全一致的。因此很多大型工程,尤其是做芯片,都有一个C或者matlab模型进行支撑,通过C模型来指导verilog设计。

FIR IP C/MATLAB模型的说明

在于pg149文档的第五章。
介绍了C模型和matlab模型,C模型的话暂时还没研究,这里主要记录下matlab模型的使用,以及自带例程的运行。

在这里插入图片描述
matlab模型使用起来也很简单,每次例化了一个FIR ip核之后,ip核的文件夹会带一个cmodel的文件夹。

在这里插入图片描述
里面包含了这两个压缩文件,lin64是在linux下使用,nt64是在windows下使用。我们解压nt64压缩文件后,也就看到了上表格中红色方框中的这些文件了。

首先,我们需要在matlab中运行 make_fir_compiler_v7_2_mex 这个文件,会生成一个fir_compiler_v7_2_bitacc_mex.mexw64这样的文件,然后,在运行 run_fir_compiler_v7_2_mex,这样matlab例程就可以运行起来的了。
还有一些详细的函数说明可以参照数据手册说的,直接通过看例程也可以快速了解该模型的使用,这里就不多说了。

注意,我这里用的是matlab2019b,操作系统是win10,vivado2019.2

FIR ip MATLAB模型的简要说明

run_fir_compiler_v7_2_mex 文件中自带5个例子。
公共参数

  fft_size     = 4096;        %FFT分析点数
  data_samples = 4096;        %数据采样点数
  window_name  = @hamming;    %窗函数

下面是使用其他窗函数的定义,

@barthannwin
@bartlett
@blackman
@blackmanharris
@bohmanwin
@chebwin
@flattopwin
@gausswin
@hamming
@hann
@kaiser
@nuttallwin
@parzenwin
@rectwin
@taylorwin
@triang
@tukeywin

使用这种@方法,实际上使用一个参数固定的典型窗函数,例如@hamming
在这里插入图片描述
对于系数的幅频响应分析方法

fr_filter   = fft(config1.coeff,fft_size);
plot(20*log10(abs(fr_filter(1:fft_size/2))./max(abs(fr_filter))));
grid on;

IP核中使用的是,没有归一化的:

plot(20*log10(abs(fr_filter(1:fft_size/2))));

在这里插入图片描述
而Xilinx IP核中的图:

在这里插入图片描述
这两个图是一样的

示例1:(Create default filter IP核默认设置)

默认设置的系数就是这个:
在这里插入图片描述

  % Constants
  fft_size     = 4096;
  data_samples = 4096;
  window_name  = @hamming;
  %window_name  = @rectwin;  %矩形窗


  % Create default filter
  disp('---------------------------------------------------------------------');
  disp('INFO: Create default filter');
  disp('---------------------------------------------------------------------');


  fir1    = fir_compiler_v7_2_bitacc()
  config1 = get_configuration(fir1);


  % Create an input data vector
  %   - Scaled to match the default models data format; Fix16_0
  disp('INFO: Generate input data...');
  data_in = 16e3*(sin(0.5*[1:1:data_samples])+sin(2*[1:1:data_samples]));


  % Filter data
  disp('INFO: Filter...');
  data_out = filter(fir1,data_in);


  % Plot normalized filter response, input data and output data
  disp('INFO: Plot filter response, input data and output data');
  fr_filter   = fft(config1.coeff,fft_size);
  fr_data_in  = fft(data_in.*window(window_name,data_samples)',fft_size);
  %fr_data_in  = fft(data_in,fft_size);
  fr_data_out = fft(data_out.*window(window_name,data_samples)',fft_size);
  %fr_data_out = fft(data_out,fft_size);
  figure;
  plot(20*log10(abs(fr_filter(1:fft_size/2))./max(abs(fr_filter))));
  hold on;
  grid on;
  plot(20*log10(abs(fr_data_in(1:fft_size/2))./max(abs(fr_data_in))),'r');
  plot(20*log10(abs(fr_data_out(1:fft_size/2))./max(abs(fr_data_out))),'g');
  legend('Filter','Data in','Data out');
  title('Default filter configuration');
  disp('Press any key to continue...'); pause;

在这里插入图片描述
看绿色的曲线,经过滤波器后,幅度正好到达滤波器的包络处

示例2:(Create 2 channel upsampling filter 双通道升采样滤波)

% Constants
  fft_size     = 4096;
  data_samples = 4096;
  window_name  = @hamming;
  %window_name  = @rectwin;  %矩形窗


  % Create 2 channel upsampling filter
  disp('---------------------------------------------------------------------');
  disp('INFO: Create 2 channel upsampling filter');
  disp('---------------------------------------------------------------------');
  disp('Press any key to continue...'); pause;
  fir3    = fir_compiler_v7_2_bitacc('filter_type',1,'interp_rate',2,'num_channels',2)
  config3 = get_configuration(fir3);


  % Create input data vector
  %   - Scaled to match the default models data format; Fix16_0
  disp('INFO: Generate input data...');
  clear data_in;
  data_in(1,:) = 16e3*(sin(0.5*[1:1:data_samples/2]));
  data_in(2,:) = 8e3*(sin(0.2*[1:1:data_samples/2]));


  % Create upsampled data with no filtering for comparison
  data_up(1,:) = upsample(data_in(1,:),2);  % 实际上是数据中间补0
  data_up(2,:) = upsample(data_in(2,:),2);  % 实际上是数据中间补0


  % Filter data
  disp('INFO: Filter...');
  data_out = filter(fir3,data_in);


  % Plot normalized filter response, input data and output data
  disp('INFO: Plot filter response, input data and output data');
  wndw(1,:)    = window(window_name,data_samples/2);
  wndw(2,:)    = window(window_name,data_samples/2);
  wndw_up(1,:) = window(window_name,data_samples);
  wndw_up(2,:) = window(window_name,data_samples);
  fr_filter      = fft(config3.coeff,fft_size);
  fr_data_in     = fft(data_in.*wndw,fft_size,2);
  fr_data_up     = fft(data_up.*wndw_up,fft_size,2);
  fr_data_out    = fft(data_out.*wndw_up,fft_size,2);
  figure;
  subplot(3,1,1);
  plot(20*log10(abs(fr_data_in(1,1:fft_size/2))./max(max(abs(fr_data_in)))),'b');
  hold on;
  grid on;
  plot(20*log10(abs(fr_data_in(2,1:fft_size/2))./max(max(abs(fr_data_in)))),'r');
  legend('Data In (ch1)','Data In (ch2)');
  title('Input data');
  subplot(3,1,2);
  plot(20*log10(abs(fr_data_up(1,1:fft_size/2))./max(max(abs(fr_data_up)))),'g');
  hold on;
  grid on;
  plot(20*log10(abs(fr_data_up(2,1:fft_size/2))./max(max(abs(fr_data_up)))),'c');
  legend('Data upsampled (ch1)','Data upsampled (ch2)');
  title('Upsampled no filtering');
  subplot(3,1,3);
  plot(20*log10(abs(fr_filter(1:fft_size/2))./max(abs(fr_filter))),'b');
  hold on;
  grid on;
  plot(20*log10(abs(fr_data_out(1,1:fft_size/2))./max(max(abs(fr_data_out)))),'r');
  plot(20*log10(abs(fr_data_out(2,1:fft_size/2))./max(max(abs(fr_data_out)))),'g');
  legend('Filter','Data upsampled (ch1)','Data upsampled (ch2)');
  title('Upsampled plus filtering');
  disp('Press any key to continue...'); pause;

在这里插入图片描述

示例3:(使用自定义抽头滤波器,且观察量化后的误差)

函数: cfirpm

b = cfirpm(n,f,@fresp)  n 阶数  f [0 FP FS 1] @lowpass 的一个用法
 % Constants
  fft_size     = 4096;
  data_samples = 4096;
  window_name  = @hamming;
  %window_name  = @rectwin;  %矩形窗


  % Create filter using coefficients created by firpm
  %   - Coefficients will be quantized by the FIR Compiler object
  disp('---------------------------------------------------------------------');
  disp('INFO: Create filter using coefficients generated by cfirpm');
  disp('---------------------------------------------------------------------');
  disp('Press any key to continue...'); pause;
  disp('INFO: Creating coefficients...');
  fl    = 99;
  f     = [0,0.2,0.3,1];
  coeff = cfirpm(fl,f,@lowpass);
  disp('INFO: Creating filter quantizing coefficients to Fix16_15 ...');
  fir4    = fir_compiler_v7_2_bitacc('coeff',coeff,'num_coeffs',fl+1,'coeff_width',16,'coeff_fract_width',15,'data_width',16,'data_fract_width',14)
  config4 = get_configuration(fir4);


  % Plot source and quantized filter coefficients
  disp('INFO: Plot quantized coefficients vs source coefficients');
  figure;
  fr_filter      = fft(config4.coeff,fft_size);
  fr_filter_quant= fft(filter(fir4,[1,zeros(1,fl)]),fft_size);

   %这个语句 filter(fir4,[1,zeros(1,fl)])
   %等价于
   %coeff1 = round(coeff*2^15)/2^15;  2^15 与coeff_fract_width参数对应
   %还没搞清楚为什么
   %plot(filter(fir4,[1,zeros(1,fl)]) - coeff1)


  plot(20*log10(abs(fr_filter(1:fft_size/2))./max(abs(fr_filter))),'b');
  hold on;
  grid on;
  plot(20*log10(abs(fr_filter_quant(1:fft_size/2))./max(abs(fr_filter_quant))),'r');
  legend('Source Coefficients','Quantized Coefficients');
  title('Coefficient Quantization');
  disp('Press any key to continue...'); pause;


  % Create an input data vector
  disp('INFO: Generate input data...');
  clear data_in;
  data_in = sin(0.5*[1:1:data_samples])+sin(2*[1:1:data_samples]);


  % Filter data
  disp('INFO: Filter...');
  data_out = filter(fir4,data_in);


  % Plot normalized filter response, input data and output data
  disp('INFO: Plot filter response, input data and output data');
  fr_data_in  = fft(data_in.*window(window_name,data_samples)',fft_size);
  fr_data_out = fft(data_out.*window(window_name,data_samples)',fft_size);
  figure;
  plot(20*log10(abs(fr_filter_quant(1:fft_size/2))./max(abs(fr_filter_quant))));
  hold on;
  grid on;
  plot(20*log10(abs(fr_data_in(1:fft_size/2))./max(abs(fr_data_in))),'r');
  plot(20*log10(abs(fr_data_out(1:fft_size/2))./max(abs(fr_data_out))),'g');
  legend('Filter','Data in','Data out');
  title('Filter using quantized coefficients');
  disp('Press any key to continue...'); pause;

量化后与没有量化幅频响应对比

在这里插入图片描述

在这里插入图片描述

标签:FIR,fr,FPGA,IP,fft,filter,abs,data,size
来源: https://blog.csdn.net/gzy0506/article/details/122400034

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有