当前位置:   article > 正文

Altera里面调用FFTip和FIRip核详细教程(上板核逻辑分析仪Quartus)_fir滤波器多通道 ip核调用

fir滤波器多通道 ip核调用

这两天做的东西要用到FIRip核,我用的是Quartus18.0网上几乎都是老版的,新版的教程说明很少,于是就研究了一下,写出来共大家一起学习

1:准备工作

    (1):FIRip核的配置

05507ef542784f0c961982651b19687d.png

我用的是单通道所以在通道选项就选者1,下面输入采样时钟50Mhz,

5d19154196bc4df29dc2ad6181c2cdb3.png

这里前面都默认,记住这里是有符号位的,并且下面输入你的采样位宽,

c84149e3060f41ef8a283d42a615eb47.png

这里我选择的是用matlab生成系数,并导入进去,matlab生成系数看后文Matlab部分,记住生成的系数写入文件要用逗号隔开,否则这个页面不显示波形,

eefe46006232495b925ed982b26ca411.png

因为是有符号位的所以比采样的位宽多一位,这里输入9,后面的都默认,在代码里面再截断选着有用的数据 (这里我花费了好长时间才搞明白),后面的都默认,最后电机Finish,接下来就是MATLAB系数的生成

(2):MATLAB系数的生成

打开Matlab,在命令行输入fdatool,进入配置选项

200c27b1551c41ea93a6851ff9ef4ff8.png

这里选择低通fir窗函数凯撒窗(如图)

7ec71c122e6d4c7bba3abb3df032daab.png

接下来在选着fix point(一定要),左边第三个,输入位宽8和Specify all

4fb39414919943eba57e99b3f3ff382f.png

选着输入位宽含符号位9,下面选着,输出也是含有符号位9和8,然后点击Apply

b6cf1db300ff488cbd446b401b9d5985.png

最后导出生成的系数,文件里选着导出到工作台

e11ea7c4c0c44500a720457a3f6e42e9.png

 

可以看到多了一个Num,接下来把数据导出到文件,

50278a31d4bf44c6930edf58dc9ca63f.png

  1. fid=fopen('C:\Users\123\Desktop\FPGA_Integrated_projects\matlab\fir_data.txt',"W")
  2. [r,c]=size(Num); % 得到矩阵的行数和列数
  3. for i=1:r
  4. for j=1:c
  5. fprintf(fid, '%f,',Num(i,j));
  6. end
  7. end
  8. fclose(fid);

到这里Matlab数据就生成好了,就可以写Verilog代码了。Firip核具体时序图可以看别的博主,这里重点讲一下怎么从FIR输出的数据里面选着有效的数据,代码写好后 打开逻辑分析仪,

294a014f7e564d7faede1ed59d9ca829.png

选着Fir输出的数据,可以看到大部分数据都是连续的,突然会有几个很大的数据进来(这是因为是符号位有负数),看一下连续的数据里面最大值是多少,然后从从这个数据的二进制位宽向下选着你输入数据的位宽,这里我选的是8,然后很大的数据变成二进制看看含1的最高位在多少,然后有效的数据取反加1,这样就完成了 代码如下

  1. module FFT_test
  2. (
  3. input wire sys_clk ,
  4. input wire sys_rst_n ,
  5. output wire [7:0] data_modulus,
  6. output wire [9:0] index ,
  7. output wire data_sop ,
  8. output wire data_eop ,
  9. output wire data_valid
  10. );
  11. wire fir_valid ;
  12. reg [7:0] address ;
  13. wire [7:0] data ;
  14. wire [7:0] fft_data_in ;
  15. wire fir_source_valid;
  16. wire [23:0]fir_data_out ;
  17. always@(posedge sys_clk or negedge sys_rst_n)
  18. if(!sys_rst_n)
  19. address <=0;
  20. else if(fir_valid==1'b1)
  21. address <=address+1;
  22. else
  23. address <=address;
  24. rom rom_inst_U1
  25. (
  26. .address ( address ),
  27. .clock ( sys_clk ),
  28. .rden ( fir_valid),
  29. .q ( data )
  30. );
  31. fir fir_U11
  32. (
  33. .clk ( sys_clk ),// clk.clk
  34. .reset_n ( sys_rst_n ),// rst.reset_n
  35. .ast_sink_data ( {1'b0,data} ),// avalon_streaming_sink.data
  36. .ast_sink_valid ( fir_valid ),// .valid
  37. .ast_sink_error ( 2'b0 ),// .error
  38. .ast_source_data ( fir_data_out ),// avalon_streaming_source.data
  39. .ast_source_valid( fir_source_valid ),// .valid
  40. .ast_source_error( ) // .error
  41. );
  42. assign fft_data_in = (fir_data_out[22]==1'b1)?(~fir_data_out[17:10]+1):fir_data_out[17:10];//非常主要,
  43. FFT_top FFT_top_U2
  44. (
  45. .sys_clk (sys_clk ) ,
  46. .sys_rst_n (sys_rst_n ) ,
  47. .data_in (fft_data_in ) ,
  48. .fir_source_valid(fir_source_valid),
  49. .data_modulus(data_modulus) ,
  50. .data_sop (data_sop ) ,
  51. .data_eop (data_eop ) ,
  52. .data_valid (data_valid ) ,
  53. .fir_valid (fir_valid ) ,
  54. .index (index)
  55. );
  56. endmodule

2:结果

这里我输入的信号在1,5,12,50,90的地方有数值,并且也输入了噪声

6a95516e97f544f0871e6ca279d15b91.png

将数据写入mif文件,并烧到rom里面(选着Mif文件)

  1. clc; %清除命令行命令
  2. clear all; %清除工作区变量,释放内存空间
  3. F1=1; %信号频率
  4. Fs=2^8; %采样频率
  5. P1=0; %信号初始相位
  6. N=2^8; %采样点数
  7. t=[0:1/Fs:(N-1)/Fs]; %采样时刻
  8. ADC=2^7 - 1; %直流分量
  9. A=2^7; %信号幅度
  10. %生成正弦信号
  11. s=A*(sin(2*pi*F1*t)+5*sin(2*pi*12*t)+sin(2*pi*50*t)+sin(2*pi*90*t)+randn(size(t)))/10+ ADC;
  12. plot(t,s); %绘制图形
  13. %创建mif文件
  14. fild = fopen('C:\Users\123\Desktop\FPGA_Integrated_projects\matlab\FFTsin_wave_256x8.mif','wt');
  15. %写入mif文件头
  16. fprintf(fild, '%s\n','WIDTH=8;'); %位宽
  17. fprintf(fild, '%s\n\n','DEPTH=4096;'); %深度
  18. fprintf(fild, '%s\n','ADDRESS_RADIX=UNS;'); %地址格式
  19. fprintf(fild, '%s\n\n','DATA_RADIX=UNS;'); %数据格式
  20. fprintf(fild, '%s\t','CONTENT'); %地址
  21. fprintf(fild, '%s\n','BEGIN'); %开始
  22. for i = 1:N
  23. s0(i) = round(s(i)); %对小数四舍五入以取整
  24. if s0(i) <0 %负1强制置零
  25. s0(i) = 0
  26. end
  27. fprintf(fild, '\t%g\t',i-1); %地址编码
  28. fprintf(fild, '%s\t',':'); %冒号
  29. fprintf(fild, '%d',s0(i)); %数据写入
  30. fprintf(fild, '%s\n',';'); %分号,换行
  31. end
  32. fprintf(fild, '%s\n','END;'); %结束
  33. fclose(fild);

9db62c3ca1e94e8f8d41c80064a06ea4.png

 在逻辑分析仪核上板上可以看到正确滤掉了90处的信号,

1cfc40794d6d44b08d129bfcd245a3c5.png

这里成功显示了几个频率并且12处的最大,90处的没有了

dbbb72ddb9d04f0bb99f7ee71699ce6a.jpeg

到这里就完成了,谢谢大家观看,全部工程需要的可以发邮箱

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号