Altera里面调用FFTip和FIRip核详细教程(上板核逻辑分析仪Quartus)

这两天做的东西要用到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

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

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

294a014f7e564d7faede1ed59d9ca829.png

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

module FFT_test
(
    input wire        sys_clk     ,
    input wire        sys_rst_n   ,
    
    output wire [7:0] data_modulus,
    output wire [9:0] index       ,
    output wire       data_sop    ,
    output wire       data_eop    ,
    output wire       data_valid  
    
);

wire          fir_valid  ;

reg  [7:0]    address      ;
wire [7:0]    data         ;
wire [7:0]    fft_data_in  ;
wire       fir_source_valid;
wire [23:0]fir_data_out    ;

always@(posedge sys_clk or negedge sys_rst_n)
    if(!sys_rst_n)
        address <=0;
    else if(fir_valid==1'b1)
        address <=address+1;
    else
        address <=address;
        
rom	rom_inst_U1
(
    .address ( address   ),
    .clock   ( sys_clk   ),
    .rden    ( fir_valid),
    .q       ( data      )
);
fir fir_U11
(
    .clk             ( sys_clk           ),//                     clk.clk
    .reset_n         ( sys_rst_n         ),//                     rst.reset_n
    .ast_sink_data   ( {1'b0,data}       ),//   avalon_streaming_sink.data
    .ast_sink_valid  ( fir_valid         ),//                        .valid
    .ast_sink_error  ( 2'b0              ),//                        .error
    .ast_source_data ( fir_data_out      ),// avalon_streaming_source.data
    .ast_source_valid( fir_source_valid  ),//                        .valid
    .ast_source_error(                   ) //                        .error
);

assign fft_data_in = (fir_data_out[22]==1'b1)?(~fir_data_out[17:10]+1):fir_data_out[17:10];//非常主要,

FFT_top FFT_top_U2
(
    .sys_clk     (sys_clk     )  ,
    .sys_rst_n   (sys_rst_n   )  ,
    .data_in     (fft_data_in )  ,
    .fir_source_valid(fir_source_valid),
    
    .data_modulus(data_modulus)  ,  
    .data_sop    (data_sop    )  ,
    .data_eop    (data_eop    )  ,
    .data_valid  (data_valid  )  ,
    .fir_valid   (fir_valid   )  ,
    .index       (index)
);
endmodule

2:结果

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

6a95516e97f544f0871e6ca279d15b91.png

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

clc;                    %清除命令行命令
clear all;              %清除工作区变量,释放内存空间
F1=1;                   %信号频率
Fs=2^8;                %采样频率
P1=0;                   %信号初始相位
N=2^8;                 %采样点数
t=[0:1/Fs:(N-1)/Fs];    %采样时刻
ADC=2^7 - 1;            %直流分量
A=2^7;                  %信号幅度
%生成正弦信号
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;
plot(t,s);                %绘制图形
%创建mif文件
fild = fopen('C:\Users\123\Desktop\FPGA_Integrated_projects\matlab\FFTsin_wave_256x8.mif','wt');
%写入mif文件头
fprintf(fild, '%s\n','WIDTH=8;');           %位宽
fprintf(fild, '%s\n\n','DEPTH=4096;');      %深度
fprintf(fild, '%s\n','ADDRESS_RADIX=UNS;'); %地址格式
fprintf(fild, '%s\n\n','DATA_RADIX=UNS;');  %数据格式
fprintf(fild, '%s\t','CONTENT');            %地址
fprintf(fild, '%s\n','BEGIN');              %开始
for i = 1:N
    s0(i) = round(s(i));    %对小数四舍五入以取整
    if s0(i) <0             %负1强制置零
        s0(i) = 0
    end
    fprintf(fild, '\t%g\t',i-1);    %地址编码
    fprintf(fild, '%s\t',':');      %冒号
    fprintf(fild, '%d',s0(i));      %数据写入
    fprintf(fild, '%s\n',';');      %分号,换行
end
fprintf(fild, '%s\n','END;');       %结束
fclose(fild);


9db62c3ca1e94e8f8d41c80064a06ea4.png

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

1cfc40794d6d44b08d129bfcd245a3c5.png

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

dbbb72ddb9d04f0bb99f7ee71699ce6a.jpeg

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

 

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值