FFT Vivado IP核實現
1、首先用matlab產生16bit二進位制正弦訊號資料,存入rom:
%設定引數
fi=5000;
L=1024;
N=16;
fs=20000;
%產生訊號
t=0:1/fs:(L-1)/fs;
theta=rand()*2*pi;
si=sin(2*pi*fi*t+theta);
f_s=si/max(abs(si));
Q_s=round(f_s*(2^(N-1)-1));
fid=fopen('C:\Users\HLPC\Desktop\Sin.txt','w');
for k=1:length(Q_s)
B_s=dec2bin(Q_s(k)+(Q_s(k)<0)*2^N,N);
for j=1:N
if B_s(j)=='1'
tb=1;
else
tb=0;
end
fprintf(fid,'%d',tb);
end
fprintf(fid,'\r\n');
end
fprintf(fid,';');
fclose(fid);
2、將資料存入rom ip核中
rom核的應用見:https://blog.csdn.net/qq_39005414/article/details/109552835
3、FFT ip核配置
`timescale 1ns / 1ps
module rom_fft(
input sys_clk_n,
input sys_clk_p,
input rst_n,
output [9:0] a,
output reg [15:0]data_i,
output m_axis_data_tvalid,
output [63:0] data_o,
output reg [26:0]fft_re,
output reg [26:0]fft_im,
output reg [54:0]fft_amp
);
wire clk;
wire [15:0]spo;
reg s_axis_config_tvalid;
wire s_axis_config_tready;
reg s_axis_data_tvalid;
reg s_axis_data_tlast;
wire m_axis_data_tlast;
wire s_axis_data_tready;
wire [63:0] m_axis_data_tdata;
wire event_frame_started;
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 cnt_flag;
reg [10:0]cnt;
wire [53:0] xkre_square, xkim_square;
assign data_o = m_axis_data_tdata;
IBUFDS CLK(
.I(sys_clk_n),
.IB(sys_clk_p),
.O(clk)
);
xfft_0 your_instance_name (
.aclk(clk), // input wire aclk
.aresetn(rst_n),
.s_axis_config_tdata(8'd1), // input wire [15 : 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({16'd0,data_i}), // 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_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tready(1'b1), // 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
);
reg [9:0] cnt1;
always @(posedge clk)begin
if(~rst_n)
cnt1 <= 1'b0;
else if(cnt1 < 10'd200)
cnt1 <= cnt1 + 1'b1;
end
always @(posedge clk)begin
if(~rst_n)
cnt_flag <= 1'b0;
else if(s_axis_config_tvalid)
cnt_flag <= 1'b1;
end
always @(posedge clk)begin
if(~rst_n)
s_axis_config_tvalid <= 1'b0;
else if(cnt1 < 10'd200)
s_axis_config_tvalid <= 1'b1;
else
s_axis_config_tvalid <= 1'b0;
end
always @(posedge clk)begin
if(~rst_n)
cnt <= 11'd0;
else if(cnt_flag )
if(cnt <= 11'd1023)
cnt <= 11'd1 + cnt;
else
cnt <= cnt;
else
cnt <= 11'd0;
end
always @(posedge clk)begin
if(~rst_n)
s_axis_data_tvalid <= 1'b0;
else if(cnt_flag && cnt <= 11'd1023)
s_axis_data_tvalid <= 1'b1;
else
s_axis_data_tvalid <= 1'b0;
end
always @(posedge clk)begin
if(~rst_n)
s_axis_data_tlast <= 1'b0;
else if(cnt == 11'd1023)
s_axis_data_tlast <= 1'b1;
else
s_axis_data_tlast <= 1'b0;
end
always @(posedge clk)begin
if(~rst_n)
fft_im <= 27'd0;
else
fft_im <= data_o[58:32];
end
always @(posedge clk)begin
if(~rst_n)
fft_re <= 27'd0;
else
fft_re <= data_o[26:0];
end
mult_gen_0 your_instance_name3 (
.CLK(clk), // input wire CLK
.A(fft_re), // input wire [26 : 0] A
.B(fft_re), // input wire [26 : 0] B
.P(xkre_square) // output wire [53 : 0] P
);
mult_gen_0 your_instance_name4 (
.CLK(clk), // input wire CLK
.A(fft_im), // input wire [26 : 0] A
.B(fft_im), // input wire [26 : 0] B
.P(xkim_square) // output wire [53 : 0] P
);
always @(posedge clk)
if(~rst_n)
fft_amp <= 55'd0;
else
fft_amp <= xkre_square + xkim_square;
dist_mem_gen_0 your_instance_name1 (
.a(a), // input wire [9 : 0] a
.clk(clk), // input wire clk
.qspo_rst(~rst_n), // input wire qspo_rst
.qspo(spo) // output wire [15 : 0] qspo
);
assign a = cnt;
always@(posedge clk or negedge rst_n)begin
if(~rst_n )
data_i <= 16'd0;
else if(a <= 10'd1023)
data_i <= spo;
end
endmodule
testbench模擬
module vtf_test(
);
wire sys_clk_n;
reg sys_clk_p;
reg rst_n;
wire [15:0] data_i;
wire [63:0] data_o;
wire [26:0] fft_re;
wire [26:0] fft_im;
wire [54:0] fft_amp;
wire [9:0] a;
wire clk;
wire m_axis_data_tvalid;
rom_fft u_rom_fft(
.sys_clk_n(sys_clk_n),
.sys_clk_p(sys_clk_p),
.rst_n(rst_n),
.a(a),
.data_i(data_i),
.m_axis_data_tvalid(m_axis_data_tvalid),
.data_o(data_o),
.fft_re(fft_re),
.fft_im(fft_im),
.fft_amp(fft_amp)
);
initial begin
rst_n = 0;
sys_clk_p = 0;
#20;
rst_n = 1;
#2000000;
end
IBUFDS CLK(
.I(sys_clk_n),
.IB(sys_clk_p),
.O(clk)
);
integer file_out;
initial
begin
//檔案放置在"工程目錄\simulation\modelsim"路徑下
file_out = $fopen("out.txt");
if(!file_out)
begin
$display("could not open file!");
$finish;
end
end
always @(posedge clk)begin
if(m_axis_data_tvalid)
$fdisplay(file_out,"%d",fft_amp);
end
integer file_out1;
initial
begin
//檔案放置在"工程目錄\simulation\modelsim"路徑下
file_out1 = $fopen("out1.txt");
if(!file_out)
begin
$display("could not open file!");
$finish;
end
end
always @(posedge clk)begin
if((a>0) && (a<10'd1023))
$fdisplay(file_out1,"%d",data_i);
end
always #5 sys_clk_p=~sys_clk_p;
assign sys_clk_n=~sys_clk_p;
endmodule
模擬結果
4、將結果輸出和matlab fft後的結果對比:
subplot(2,1,1)
cstr = textread('D:\fpga_test\rom_fft\rom_fft.sim\sim_1\behav\xsim\out.txt','%d');
plot(cstr)
subplot(2,1,2)
cstr1 = textread('C:\Users\HLPC\Desktop\Sin.txt','%d');
plot(abs(fft(cstr1)))
相關文章
- Vivado使用技巧(8):Core Container打包IP核AI
- Vivado使用技巧(10):編輯與改寫IP核原始檔
- Vivado使用技巧(7):使用IP核自帶Testbench進行模擬
- Vivado開發環境,將COE檔案加入IP核ROM中開發環境
- modelsim 獨立模擬vivado的IP核及模擬指令碼指令碼
- HDL/FPGA學習筆記二十五:Vivado PLL IP核的使用FPGA筆記
- Vivado DDS IP核使用和模擬(一、單通道訊號發生器)
- Quartus Ⅱ呼叫FIFO IP核方法實現求和(Mega Wizard)
- C#實現FFT(遞迴法)C#FFT遞迴
- (9)FIFO ip核
- IP核之ROM
- FFT演算法實現與分析MATLABFFT演算法Matlab
- IP核:XDMA學習
- VIVADO vhdl verilog 實現矩陣運算矩陣
- FFTFFT
- nexys4DDR 實現自定義IP核掛載到axi_4匯流排
- FPGA的時鐘IP核知識點FPGA
- QuartusII呼叫 PLL_IP核方法(Mega Wizard)
- PyQT5 實現下拉核取方塊QT
- 一種動態實現核隔離的方法
- JS實現核取方塊全選反選JS
- Vivado實戰—單週期CPU指令分析
- Golang實現的IP代理池Golang
- 分治FFT小記?FFT
- jquery實現checkbox核取方塊全選效果jQuery
- Python實現ping指定IPPython
- 【RAC】RAC 實現IP訪問控制
- 1(5)led燈閃爍、常見ip核介紹
- Vivado入門教程
- FFT模板(無講解)FFT
- [學習筆記] FFT筆記FFT
- FFT學習筆記FFT筆記
- js實現checkbox核取方塊的反選效果JS
- jQuery如何實現核取方塊全選和全不選jQuery
- 遠超美國、日本!中國核技術實現突破:真牛
- 手寫fft演算法,和內建fft演算法對比FFT演算法
- golang實現抓取IP地址的蜘蛛程式Golang
- 各大主流社交軟體顯示ip地址-如何實現ip飄移