1. 今日摸鱼任务
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 学习Vivado FFT IP核的使用 |
| Vivado_FFT IP核 使用详解_vivado fft ip核-CSDN博客 这篇写的很详细啦 简单做一点笔记进行记录 |
2. FFT IP核
xfft_0 ff (
.aclk(aclk), // input wire aclk
.aresetn(aresetn), // input wire aresetn
.s_axis_config_tdata(s_axis_config_tdata), // input wire [23 : 0] s_axis_config_tdata
.s_axis_config_tvalid(s_axis_config_tvalid), // input wire s_axis_config_tvalid
.s_axis_config_tready(s_axis_config_tready), // output wire s_axis_config_tready
.s_axis_data_tdata(s_axis_data_tdata), // input wire [31 : 0] s_axis_data_tdata
.s_axis_data_tvalid(s_axis_data_tvalid), // input wire s_axis_data_tvalid
.s_axis_data_tready(s_axis_data_tready), // output wire s_axis_data_tready
.s_axis_data_tlast(s_axis_data_tlast), // input wire s_axis_data_tlast
.m_axis_data_tdata(m_axis_data_tdata), // output wire [31 : 0] m_axis_data_tdata
.m_axis_data_tuser(m_axis_data_tuser), // output wire [7 : 0] m_axis_data_tuser
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tready(m_axis_data_tready), // input wire m_axis_data_tready
.m_axis_data_tlast(m_axis_data_tlast), // output wire m_axis_data_tlast
.event_frame_started(event_frame_started), // output wire event_frame_started
.event_tlast_unexpected(event_tlast_unexpected), // output wire event_tlast_unexpected
.event_tlast_missing(event_tlast_missing), // output wire event_tlast_missing
.event_status_channel_halt(event_status_channel_halt), // output wire event_status_channel_halt
.event_data_in_channel_halt(event_data_in_channel_halt), // output wire event_data_in_channel_halt
.event_data_out_channel_halt(event_data_out_channel_halt) // output wire event_data_out_channel_halt
);
看起来有这么多端口,貌似很麻烦捏:
AXI4-Stream这里重点是TVALID和TREADY:分清输入输出的主、从
3. matlab 程序
clc;clear;close all;
fs = 1e4;f1 = 5e2;
N = 1024;
t = 0:1/fs:(N-1)/fs;
x = sin(2*pi*f1*t) ;
x = mapminmax(x).* (2^15-1);
fid = fopen('fft_test_signal.txt', 'wt');
for i = 1:N
if (x(i) >= 0)
fprintf(fid, '%s\n', dec2bin(x(i),16));
else
fprintf(fid, '%s\n', dec2bin(2^16 + x(i), 16));
end
end
fclose(fid);
y = fft(x(1:1024)) / 2^12;%缩放倍数在s_axis_config_tdata处
y_re = real(y);
y_im = imag(y);
figure(1);
subplot(3,1,1);plot(0:N-1,x);title('x = sin(2*pi*500*t) fs = 10kHz');
subplot(3,1,2);plot(0:N-1,y_re);title('y re');
subplot(3,1,3);plot(0:N-1,y_im);title('y im');
4. FFT 配置与验证
`timescale 1ns / 1ns
module fft_tb( );
reg aclk;
reg aresetn;
reg [23:0] s_axis_config_tdata;
reg s_axis_config_tvalid;
reg [31:0] s_axis_data_tdata;
reg s_axis_data_tvalid;
reg s_axis_data_tlast;
reg m_axis_data_tready;
wire [31:0] m_axis_data_tdata;
wire [9:0] m_axis_data_tuser;
wire m_axis_data_tlast;
wire m_axis_data_tvalid;
wire s_axis_config_tready;
wire s_axis_data_tready;
wire event_frame_started;
wire event_tlast_unexpectedl;
wire event_tlast_unexpected;
wire event_tlast_missing;
wire event_status_channel_halt;
wire event_data_in_channel_halt;
wire event_data_out_channel_halt;
reg [15:0] data_in[0:1024-1];
integer i;
wire [15:0] Xk_Re, Xk_Im;
assign Xk_Re = m_axis_data_tdata[31:16];
assign Xk_Im = ~m_axis_data_tdata[15:0]+1'b1;//取反
initial aclk = 1'b1;
always#10aclk = ~aclk ;
initial
begin
$readmemb("E:/vivado/fft/fft_test_signal.txt", data_in);
aresetn = 1'b0;
s_axis_config_tdata = {7'b000_0000, 16'b_01_01_10_01_10_10_01_10, 1'b1};
//s缩放倍数 1+1+2+1+2+2+1+2=12 2的12次幂对应matlab
s_axis_config_tvalid = 1'b1;
i = 0;
s_axis_data_tdata = 32'd0;
s_axis_data_tlast = 1'b0;
m_axis_data_tready = 1'b1;
# 40;
aresetn = 1'b1;
forever
begin
@(negedge aclk)
if(s_axis_data_tready == 1'b1)
begin
s_axis_data_tvalid = 1'b1;
s_axis_data_tdata = {data_in[i], 16'd0};
if(i == 1024-1) i = 0;
else i = i+1;
end
else
s_axis_data_tvalid = 1'b0;
end
$stop;
end
xfft_0 ff (
.aclk(aclk), // input wire aclk
.aresetn(aresetn), // input wire aresetn
.s_axis_config_tdata(s_axis_config_tdata), // input wire [23 : 0] s_axis_config_tdata
.s_axis_config_tvalid(s_axis_config_tvalid), // input wire s_axis_config_tvalid
.s_axis_config_tready(s_axis_config_tready), // output wire s_axis_config_tready
.s_axis_data_tdata(s_axis_data_tdata), // input wire [31 : 0] s_axis_data_tdata
.s_axis_data_tvalid(s_axis_data_tvalid), // input wire s_axis_data_tvalid
.s_axis_data_tready(s_axis_data_tready), // output wire s_axis_data_tready
.s_axis_data_tlast(s_axis_data_tlast), // input wire s_axis_data_tlast
.m_axis_data_tdata(m_axis_data_tdata), // output wire [31 : 0] m_axis_data_tdata
.m_axis_data_tuser(m_axis_data_tuser), // output wire [9: 0] m_axis_data_tuser
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tready(m_axis_data_tready), // input wire m_axis_data_tready
.m_axis_data_tlast(m_axis_data_tlast), // output wire m_axis_data_tlast
.event_frame_started(event_frame_started), // output wire event_frame_started
.event_tlast_unexpected(event_tlast_unexpected), // output wire event_tlast_unexpected
.event_tlast_missing(event_tlast_missing), // output wire event_tlast_missing
.event_status_channel_halt(event_status_channel_halt), // output wire event_status_channel_halt
.event_data_in_channel_halt(event_data_in_channel_halt), // output wire event_data_in_channel_halt
.event_data_out_channel_halt(event_data_out_channel_halt) // output wire event_data_out_channel_halt
);
endmodule
这个取补码可以正数变负数、负数变正数(这个小问题下周推导一下)
对于有符号数,右键Radix--> Signed Decimal
对于模拟波形显示,可以右键--> Waveform Style --> Analog Settings
//下班下班