环境
Vivado Modelsim 仿真
层次结构
ROM matlab产生波形,保存到coe文件中,加载到rom中 dds 控制输入信号的频率 dds的输出信号给到fft IP核
仿真
左边为input,右边为output 输入信号的范围为0-255,包含直流分量,频率为单频
实现
HDL
顶层文件
module ip_fft(
input clk,
input rst
);
wire [7:0] Out;
wire [10:0] addr;
wire [31:0] fft_s_axis_data_tdata;
reg fft_s_axis_data_tvalid;
wire fft_s_axis_data_tready;
reg fft_s_axis_data_tlast;
wire [63:0] m_axis_data_tdata;
wire [7:0] m_axis_data_tuser;
wire m_axis_data_tvalid;
wire m_axis_data_tlast;
wire m_axis_data_tready;
reg [7:0] counter;
reg fft_flag;
assign fft_s_axis_data_tdata = {24'b0, Out};
assign m_axis_data_tready = 1'b1;
always @(posedge clk ) begin
if (!rst) begin
counter <= 8'b0;
end
else if(fft_s_axis_data_tready) begin
counter <= counter +1'b1;
end
end
always @(posedge clk ) begin
fft_s_axis_data_tvalid <= fft_s_axis_data_tvalid;
fft_s_axis_data_tlast <= 1'b0 ;
fft_flag <= fft_flag;
if (!rst) begin
fft_flag <= 1'b0;
fft_s_axis_data_tlast <= 1'b0;
fft_s_axis_data_tvalid <= 1'b0;
end
else if(fft_flag == 1'b0) begin
if (counter == 8'hff) begin
fft_flag <= 1'b1;
fft_s_axis_data_tvalid <= 1'b1;
end
end
else if(fft_flag == 1'b1) begin
if (counter == 8'hff) begin
fft_s_axis_data_tvalid <= 1'b0;
fft_s_axis_data_tlast <= 1'b1;
end
end
else begin
fft_s_axis_data_tvalid <= fft_s_axis_data_tvalid;
fft_s_axis_data_tlast <= fft_s_axis_data_tlast ;
end
end
wire [24:0] realp;
wire [24:0] imagp;
wire [50:0] fft_abs;
assign realp = m_axis_data_tdata[56:32];
assign imagp = m_axis_data_tdata[24:0];
assign fft_abs = $signed(realp)* $signed(realp)+ $signed(imagp)* $signed(imagp);
xfft_0 u_xfft_0 (
.aclk (clk),
.aresetn (rst),
.s_axis_config_tdata (8'b1),
.s_axis_config_tvalid (1'b1),
.s_axis_config_tready (),
.s_axis_data_tdata (fft_s_axis_data_tdata),
.s_axis_data_tvalid (fft_s_axis_data_tvalid),
.s_axis_data_tready (fft_s_axis_data_tready),
.s_axis_data_tlast (fft_s_axis_data_tlast),
.m_axis_data_tdata (m_axis_data_tdata),
.m_axis_data_tuser (m_axis_data_tuser),
.m_axis_data_tvalid (m_axis_data_tvalid),
.m_axis_data_tready (m_axis_data_tready),
.m_axis_data_tlast (m_axis_data_tlast),
.event_frame_started ( ),
.event_tlast_unexpected ( ),
.event_tlast_missing ( ),
.event_status_channel_halt ( ),
.event_data_in_channel_halt ( ),
.event_data_out_channel_halt( )
);
dds u_dds (
.clk ( clk ),
.rst ( rst ),
.Fword ( 32'h800_0000 ),
.Pword ( 11'b0 ),
.Out ( Out ),
.addr ( addr )
);
endmodule
仿真文件
module tb_ip_fft;
parameter PERIOD = 10;
reg clk = 0 ;
reg rst = 0 ;
initial
begin
forever #(PERIOD/2) clk=~clk;
end
initial
begin
#(PERIOD*4) rst = 1;
end
ip_fft u_ip_fft (
.clk ( clk ),
.rst ( rst )
);
endmodule
dds文件
module dds(
input clk,
input rst,
input [31:0]Fword,
input [10:0]Pword,
output [7:0]Out,
output [10:0] addr
);
reg [31:0] r_Fword;
reg [10:0] r_Pword;
reg [31:0] cnt;
always @(posedge clk ) begin
r_Fword = Fword;
r_Pword = Pword;
end
always @(posedge clk or negedge rst) begin
if(!rst)
cnt <= 0;
else
cnt <= cnt+r_Fword;
end
assign addr = cnt[31:21]+r_Pword;
blk_mem_gen_0 u_blk_mem_gen_0 (
.clka (clk),
.ena (1'b1),
.addra (addr),
.douta (Out)
);
endmodule
IP配置
FFT
ROM
COE文件生成
matlab 代码,产生coe文件
%%
clc;
t=0:2*pi/(2^11-1):2*pi;
y=0.5*sin(t)+0.5;
figure; subplot(1,3,1); plot(y);
r=ceil(y*(2^8-1)); %将小数转换为整数,ceil是向上取整。
fid = fopen('sin.coe','w+'); %写到sin.coe文件,用来初始化sin_rom
fprintf(fid,'memory_initialization_radix=10;\n');
fprintf(fid,'memory_initialization_vector= \n');
for i = 1:1:2^11
fprintf(fid,'%d',r(i));
if i==2^11
fprintf(fid,'; ');
else
fprintf(fid,', ');
end
% if i%15==0
% fprintf(fid,'\n');
% end
end
fclose(fid);
reference
vivado 基于FPGA的dds学习记录 Vivado中FFT IP核的使用
都看到这儿了,点个赞吧!
|