fpga对信号做fft变化之后输出会随频率而改变的问题

我现在在用ad9226把信号传输给fpga 然后再通过fft做信号分析
采样频率是32Mhz 采样点数是512个 具体配置如下
QQ图片20210902203158.png
我测试的频率是1Mhz的正弦信号和8Mhz的正弦信号 两个信号都是2v的峰峰值
接下来是signaltap的调试结果(我这个工程有一个小bug 地址位错了一位)
(第一行是幅值的平方)
1Mhz:
1.png
42381开根号/2048102 约等于2v
QQ图片20210902203853.png
数值在128(16*8)处 可以看到数据的地址是没有问题的
但是数值却不是42381 而且偏差很大。

对此我认为 可能和旋转因子的系数配置 以及 source_exp 这个输出端口的理解不到位,或者是对brust的传输格式的不了解,希望有大佬能答疑解惑。

这个是代码:

module altera_fft(
input clk, //时钟
input rst_n, //低电平有效复位
input signed [11:0] data_in, //AD采集数据输入
output signed [24:0] amp, //FFT计算结果
output reg [119:0] fft_re_im,
output signed [11:0] xkre, // 输出,输出数据的实部,二进制补码数据
output signed [11:0] xkim, // 输出,输出数据的虚部
output source_valid,
output [3:0] source_exp
);

/********** 定义FFT IP核使用端口 **********/
wire inverse;         // 输入,为1时进行IFFT,为0时进行FFT
wire sink_ready;      // 输出,FFT引擎准备好接收数据时该信号置位
wire source_ready;    // 输入,下传流模块在可以接收数据时将该信号置位
reg sink_valid;       // 输入,有效标记信号,sink_valid和sink_ready都置位时开始数据传输
reg sink_sop;         // 输入,高电平表示1帧数据载入开始
reg sink_eop;         // 输入,高电平表示1帧数据载入结束
wire signed [11:0]sink_imag;  // 输入,输入数据的虚部,二进制补码数据
wire [1:0] sink_error;        // 输入,表示载入数据状态,一般置0
wire [1:0] source_error;      // 输出,表示FFT转换出现的错误
wire source_sop;              // 输出,高电平表示一帧数据转换开始
wire source_eop;              // 输出,高电平表示一帧数据转换结束

 reg    [11:0]     addr;

assign sink_error = 2'b00;
assign source_ready = 1'b1;   // 该信号置1表示永远准备好接收FFT数据
assign inverse = 1'b0;        // 进行FFT正变换
assign sink_imag = 12'd0;     // 输入数据虚部接地

/********** 控制FFT数据的载入 **********/

//在sink_valid为高电平期间,通过sink_sop、sink_eop控制载入数据
//设置FFT变换起始脉冲,sink_eop/sink_sop高电平后开始载入数据
//由于Burst模式下,FFT变换时延不超过2048个时钟周期,因此每2048个周期进行一次FFT变换
reg [10:0] count;        

always @ (posedge clk or negedge rst_n)
    if (!rst_n) begin
        sink_eop <= 'b0;
        sink_sop <= 'b0;
        sink_valid <= 'b0;
        count <= 'b0;
    end
    else begin
        count <= count + 1'd1;
        if (count == 1) sink_sop <= 1'b1;   //计数1,置位sop,开始载入AD数据
        else  sink_sop <= 1'b0;

        if (count ==512) sink_eop <= 1'b1; //计数512,置位eop,结束载入AD数据,进行512点FFT
        else  sink_eop <= 1'b0;

        if (count>=1 & count<=512) sink_valid <= 1'b1;  //载入数据期间,置位sink_valid
        else  sink_valid <= 1'b0;
    end

/********** 调用IP核进行FFT变换,Burst模式 **********/
//FFT核,实现512点的FFT正变换,在sink_valid\sink_sop\sink_eop的控制下,每2048个数据进行一次正变换
AD9226_FFT u0 (
    .clk          (clk),              
    .reset_n      (rst_n),            
    .sink_valid   (sink_valid),       
    .sink_ready   (sink_ready),      
    .sink_error   (sink_error),      
    .sink_sop     (sink_sop),         
    .sink_eop     (sink_eop),         
    .sink_real    (data_in),          
    .sink_imag    (sink_imag),    

    .inverse      (inverse),      
    .source_valid (source_valid), 
    .source_ready (source_ready), 
    .source_error (source_error), 
    .source_sop   (source_sop),   
    .source_eop   (source_eop),  
    .source_exp   (source_exp),
    .source_real  (xkre),  
    .source_imag  (xkim)   
);  

/********** 计算频谱的幅值信号 **********/
wire signed [23:0] xkre_square, xkim_square;
assign xkre_square = xkre * xkre;
assign xkim_square = xkim * xkim;
assign amp = xkre_square + xkim_square;
编辑 重设标签(回车键确认) 标为违禁 关闭 合并 删除
匿名用户

匿名