思路:
DDS信号发生器生成一个固定频率的正交信号。(DDS:直接数字频率合成技术,利用正弦波相位线性增加的特点,产生正弦波和余弦波,频率和相位可以设定。利用DDS技术,生成我们所需要的的信号);
实例化FFT IP核,分别作为FFT、IFFT交换;
将信号发生器信号输入到FFT,再将FFT信号输出到IFFT中。
project 2出错,使用了fft_ifft_test
1.DDS信号发生器产生 固定频率正弦信号
调用DDS IP核,进行如下设置,生成10MHz正弦信号
2.调用 FFT IP核,进行如下设置
3. 编写verilog程序,实例化IP核,将3个模块连接起来
代码如下,例化一个DDS输入10MHz正交信号,例化2个FFT,分别用作FFT、IFFT
`timescale 1ns / 1ps
//
module fft(
input aclk,
input aresetn,
output [7:0] fft_real,
output [7:0] fft_imag,
output [7:0] ifft_real,
output [7:0] ifft_imag
);
//-----------------DDS core(44.96MHz)------------------
wire [15:0] dds_m_data_tdata;
wire fft_s_data_tready;
wire dds_m_data_tvalid;
wire dds_m_data_tlast;//未使用
dds_compiler_0 dds_MHz (
.aclk(aclk),
.aresetn(aresetn),
.m_axis_data_tdata(dds_m_data_tdata),
.m_axis_data_tready(fft_s_data_tready),
.m_axis_data_tvalid(dds_m_data_tvalid)
);
//----------------------FFT core-------------------
wire [7:0] fft_s_config_tdata;//[0:0]FWD_INV_0
wire fft_s_config_tready;
wire fft_s_config_tvalid;
wire [7:0] fft_m_status_tdata;
wire fft_m_status_tready;
wire fft_m_status_tvalid;
wire [15:0] fft_m_data_tdata;
wire fft_m_data_tlast;
wire ifft_s_data_tready;
wire [23:0] fft_m_data_tuser; //[11:0]XK_INDEX
wire fft_m_data_tvalid;
wire fft_event_frame_started;
wire fft_event_tlast_unexpected;
wire fft_event_tlast_missing;
wire fft_event_status_channel_halt;
wire fft_event_data_in_channel_halt;
wire fft_event_data_out_channel_halt;
wire [11:0] xk_index;
assign xk_index = fft_m_data_tuser[11:0];
assign fft_s_config_tdata = 8'd1; //定义FFT模块配置信息(第0位为1表示用FFT,为0表示用IFFT)
assign fft_s_config_tvalid = 1'd1; //FFT模块配置使能,从一开始就拉高,表示已经准备好要传入的配置数据了
xfft_0 usr_fft(
.aclk(aclk),//Rising-edge clock
.aresetn(aresetn),//(低有效)Active-Low synchronous clear (optional, always take priority over aclken); A minimum aresetn active pulse of two cycles is required
//S_AXIS_DATA
.s_axis_data_tdata(dds_m_data_tdata),//IN Carries the unprocessed sample data: XN_RE and XN_IM
.s_axis_data_tlast(dds_m_data_tlast),//IN Asserted by the external master on the last sample of the frame
.s_axis_data_tready(fft_s_data_tready),//OUT Used by the core to signal that it is ready to accept data
.s_axis_data_tvalid(dds_m_data_tvalid),//IN Used by the external master to signal that it is able to provide data
//S_AXIS_CONFIG
.s_axis_config_tdata(fft_s_config_tdata),//IN Carries the configuration information
.s_axis_config_tready(fft_s_config_tready),//OUT Asserted by the core to signal that it is ready to accept data
.s_axis_config_tvalid(fft_s_config_tvalid),//IN Asserted by the external master to signal that it is able to provide data
//M_AXIS_STATUS
.m_axis_status_tdata(fft_m_status_tdata),
.m_axis_status_tready(fft_m_status_tready),
.m_axis_status_tvalid(fft_m_status_tvalid),
//M_AXIS_DATA
.m_axis_data_tdata(fft_m_data_tdata),//OUT Carries the processed sample data XK_RE and XK_IM
.m_axis_data_tlast(fft_m_data_tlast),//OUT Asserted by the core on the last sample of the frame
.m_axis_data_tready(ifft_s_data_tready),//IN Asserted by the external slave to signal that it is ready to accept data. Only present in Non-Realtime mode
.m_axis_data_tuser(fft_m_data_tuser),//OUT Carries additional per-sample information: XK_INDEX, OVFLO and BLK_EXP
.m_axis_data_tvalid(fft_m_data_tvalid),//OUT Asserted by the core to signal that it is able to provide status data
//EVENTS
.event_frame_started(fft_event_frame_started),//Asserted when the core starts to process a new frame
.event_tlast_unexpected(fft_event_tlast_unexpected),//Asserted when the core sees s_axis_data_tlast High on a data sample that is not the last one in a frame
.event_tlast_missing(fft_event_tlast_missing),//Asserted when s_axis_data_tlast is Low on the last data sample of a frame
.event_status_channel_halt(fft_event_status_channel_halt),//Asserted when the core tries to write data to the Status channel and it is unable to do so
.event_data_in_channel_halt(fft_event_data_in_channel_halt),//Asserted when the core requests data from the Data Input channel and none is available
.event_data_out_channel_halt(fft_event_data_out_channel_halt)//Asserted when the core tries to write data to the Data Output channel and it is unable to do so
);
//-----------------------------IFFT core----------------------------
wire [7:0] ifft_s_config_tdata;//[0:0]FWD_INV_0
wire ifft_s_config_tready;
wire ifft_s_config_tvalid;
wire [7:0] ifft_m_status_tdata;
wire ifft_m_status_tready;
wire ifft_m_status_tvalid;
wire [15:0] ifft_m_data_tdata;
wire ifft_m_data_tlast;
wire ifft_m_data_tready;
wire [23:0] ifft_m_data_tuser;//[11:0]XK_INDEX
wire ifft_m_data_tvalid;
wire ifft_event_frame_started;
wire ifft_event_tlast_unexpected;
wire ifft_event_tlast_missing;
wire ifft_event_status_channel_halt;
wire ifft_event_data_in_channel_halt;
wire ifft_event_data_out_channel_halt;
wire [11:0] ixk_index;
assign ixk_index = ifft_m_data_tuser[11:0];
assign ifft_s_config_tdata = 8'd0;//定义FFT模块配置信息(第0位为1表示用FFT)
assign ifft_s_config_tvalid = 1'd1;//FFT模块配置使能,从一开始就拉高,表示已经准备好要传入的配置数据了
assign ifft_m_data_tready = 1'd1;//从一开始就拉高,表示已经准备好接收IFFT模块输出的数据
xfft_0 usr_ifft(
.aclk(aclk),//Rising-edge clock
.aresetn(aresetn),//(低有效)Active-Low synchronous clear (optional, always take priority over aclken); A minimum aresetn active pulse of two cycles is required
//S_AXIS_DATA
.s_axis_data_tdata(fft_m_data_tdata),//IN Carries the unprocessed sample data: XN_RE and XN_IM
.s_axis_data_tlast(fft_m_data_tlast),//IN Asserted by the external master on the last sample of the frame
.s_axis_data_tready(ifft_s_data_tready),//OUT Used by the core to signal that it is ready to accept data
.s_axis_data_tvalid(fft_m_data_tvalid),//IN Used by the external master to signal that it is able to provide data
//S_AXIS_CONFIG
.s_axis_config_tdata(ifft_s_config_tdata),//IN Carries the configuration information
.s_axis_config_tready(ifft_s_config_tready),//OUT Asserted by the core to signal that it is ready to accept data
.s_axis_config_tvalid(ifft_s_config_tvalid),//IN Asserted by the external master to signal that it is able to provide data
//M_AXIS_STATUS
.m_axis_status_tdata(ifft_m_status_tdata),
.m_axis_status_tready(ifft_m_status_tready),
.m_axis_status_tvalid(ifft_m_status_tvalid),
//M_AXIS_DATA
.m_axis_data_tdata(ifft_m_data_tdata),//OUT Carries the processed sample data XK_RE and XK_IM
.m_axis_data_tlast(ifft_m_data_tlast),//OUT Asserted by the core on the last sample of the frame
.m_axis_data_tready(ifft_m_data_tready),//IN Asserted by the external slave to signal that it is ready to accept data. Only present in Non-Realtime mode
.m_axis_data_tuser(ifft_m_data_tuser),//OUT Carries additional per-sample information: XK_INDEX, OVFLO and BLK_EXP
.m_axis_data_tvalid(ifft_m_data_tvalid),//OUT Asserted by the core to signal that it is able to provide status data
//EVENTS
.event_frame_started(ifft_event_frame_started),//Asserted when the core starts to process a new frame
.event_tlast_unexpected(ifft_event_tlast_unexpected),//Asserted when the core sees s_axis_data_tlast High on a data sample that is not the last one in a frame
.event_tlast_missing(ifft_event_tlast_missing),//Asserted when s_axis_data_tlast is Low on the last data sample of a frame
.event_status_channel_halt(ifft_event_status_channel_halt),//Asserted when the core tries to write data to the Status channel and it is unable to do so
.event_data_in_channel_halt(ifft_event_data_in_channel_halt),//Asserted when the core requests data from the Data Input channel and none is available
.event_data_out_channel_halt(ifft_event_data_out_channel_halt)//Asserted when the core tries to write data to the Data Output channel and it is unable to do so
);
//----------------将FFT/IFFT处理完的信号传出(虚部/实部分别传出)-------
assign fft_real = fft_m_data_tdata[7:0];
assign fft_imag = fft_m_data_tdata[15:8];
assign ifft_real = ifft_m_data_tdata[7:0];
assign ifft_imag = ifft_m_data_tdata[15:8];
endmodule
4. 编写仿真文件
`timescale 1ns / 1ps
module fft_tb(
);
reg aclk,aresetn;
wire [7:0] fft_real,fft_imag;
wire [7:0] ifft_real,ifft_imag;
fft fft_test(
.aclk(aclk),
.aresetn(aresetn),
.fft_real(fft_real),
.fft_imag(fft_imag),
.ifft_real(ifft_real),
.ifft_imag(ifft_imag)
);
initial
begin
aclk = 0;
aresetn = 0;//低有效
#10 aresetn = 1;
end
always #5 aclk=~aclk;//时钟频率100MHz
//-----------将FFT变换结果写入文件-------------(下面的可以删除)
integer w_file;
initial w_file = $fopen("/自己的路径/fft_real.txt");
always @(posedge aclk)
begin
$fdisplay(w_file,"%b",fft_real);//写数据
end
integer w_file2;
initial w_file2 = $fopen("/自己的路径/fft_imag.txt");
always @(posedge aclk)
begin
$fdisplay(w_file2,"%b",fft_imag);
end
endmodule
5. run behavioral simulation运行仿真
生成图形如下:
将IFFT波形信号调整为模拟有符号十进制,可以看到下图IFFT输出的波形。可以根据图中的时钟信号计算出波形周期为100ns,即频率为10MHz
参考,
原文链接https://blog.csdn.net/luobluesky/article/details/90516652