其他分享
首页 > 其他分享> > FPGA信号处理系列文章——Xilinx FIR IP的matlab模型的使用

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

作者:互联网

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

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