我现在在用ad9226把信号传输给fpga 然后再通过fft做信号分析
采样频率是32Mhz 采样点数是512个 具体配置如下
我测试的频率是1Mhz的正弦信号和8Mhz的正弦信号 两个信号都是2v的峰峰值
接下来是signaltap的调试结果(我这个工程有一个小bug 地址位错了一位)
(第一行是幅值的平方)
1Mhz:
42381开根号/2048102 约等于2v
数值在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;
没有回复内容