0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心
发布

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基2FFT的verilog代码实现及仿真

CHANBAEK 来源:FPGA自学笔记分享 作者:FPGA自学笔记分享 2023-06-02 12:38 次阅读

上文基2FFT的算法推导及python仿真推导了基2FFT的公式,并通过python做了算法验证,本文使用verilog实现8点基2FFT的代码。

根据算法推导,8点FFT的verilog代码整体结构为:

图片

verilog代码实现首先进行2点FFT的实现,代码主要做D0+D1操作和(D0+D1)*W02操作,代码及操作内容如下:

图片

// ============================================================// File Name: cm_fft2_N2// VERSION : V1.0// DATA : 2023/1/1// Author :FPGA干货分享// ============================================================// 功能:基2FFT N=2的数据处理// delay : 2clk// ============================================================`timescale 1ns/100ps module cm_fft2_N2 #( parameter C_DATA_WITH = 16 ) (inputwire I_sys_clk ,/// 工作时钟100Minputwire I_data_start ,/// 数据开始进入标志,与第一个数据对齐输入inputwire [C_DATA_WITH-1:0] I_data_in_real ,/// 数据输入,从start开始连续输入inputwire [C_DATA_WITH-1:0] I_data_in_imag ,/// 数据输入,从start开始连续输入outputregO_data_start ,/// 数据开始输出标志与第一个数据对齐输出outputreg[C_DATA_WITH:0] O_data_out_real ,/// 数据输出,从start开始连续输出outputreg[C_DATA_WITH:0] O_data_out_imag/// 数据输出,从start开始连续输出);// ============================================================// 内部参数// ============================================================/// W02=1// ============================================================// 变量// ============================================================regS_data_start ;reg[C_DATA_WITH-1:0] S_data_in_real_d1 ;reg[C_DATA_WITH-1:0] S_data_in_real_d2 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d1 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d2 ;// ============================================================// main code// ============================================================always @(posedge I_sys_clk) begin S_data_start <= I_data_start ; O_data_start <= S_data_start ; end/// 缓存第一个数always @(posedge I_sys_clk) begin S_data_in_real_d1 <= I_data_in_real ; S_data_in_real_d2 <= S_data_in_real_d1 ; S_data_in_imag_d1 <= I_data_in_imag ; S_data_in_imag_d2 <= S_data_in_imag_d1 ; end always @(posedge I_sys_clk)if(S_data_start)/// x(n)+x(n+N/2)begin O_data_out_real <= {S_data_in_real_d1[C_DATA_WITH-1],S_data_in_real_d1} + {I_data_in_real[C_DATA_WITH-1],I_data_in_real} ; O_data_out_imag <= {S_data_in_imag_d1[C_DATA_WITH-1],S_data_in_imag_d1} + {I_data_in_imag[C_DATA_WITH-1],I_data_in_imag} ; endelseif(O_data_start)/// [x(n)-x(n+N/2)]C_W02begin O_data_out_real <= {S_data_in_real_d2[C_DATA_WITH-1],S_data_in_real_d2} - {S_data_in_real_d1[C_DATA_WITH-1],S_data_in_real_d1} ; O_data_out_imag <= {S_data_in_imag_d2[C_DATA_WITH-1],S_data_in_imag_d2} - {S_data_in_imag_d1[C_DATA_WITH-1],S_data_in_imag_d1} ; endelsebegin O_data_out_real <= 'd0; O_data_out_imag <= 'd0; end endmodule

四点FFT的代码实现如下,要注意4点FFT中W04=1,W14=-j,代码实现中要注意。

图片

// ============================================================// File Name: cm_fft2_N4// VERSION : V1.0// DATA : 2023/1/1// Author : FPGA干货分享// ============================================================// 功能:基2FFT N=4的数据处理// delay : 5clk// ============================================================`timescale 1ns/100ps module cm_fft2_N4 #( parameter C_DATA_WITH = 16 ) (inputwire I_sys_clk ,/// 工作时钟 100Minputwire I_data_start ,/// 数据开始进入标志,与第一个数据对齐输入inputwire [C_DATA_WITH-1:0] I_data_in_real ,/// 数据输入,从start开始连续输入inputwire [C_DATA_WITH-1:0] I_data_in_imag ,/// 数据输入,从start开始连续输入output wire O_data_start ,/// 数据开始输出标志与第一个数据对齐输出output wire [C_DATA_WITH+1:0] O_data_out_real ,/// 数据输出,从start开始连续输出output wire [C_DATA_WITH+1:0] O_data_out_imag/// 数据输出,从start开始连续输出);// ============================================================// 内部参数// ============================================================/// W04=1/// W14=-j// ============================================================// 变量// ============================================================regS_data_start_d1 ;regS_data_start_d2 ;regS_data_start_d3 ;regS_data_start_d4 ;regS_data_start_d5 ;reg[C_DATA_WITH-1:0] S_data_in_real_d1 ;reg[C_DATA_WITH-1:0] S_data_in_real_d2 ;reg[C_DATA_WITH-1:0] S_data_in_real_d3 ;reg[C_DATA_WITH-1:0] S_data_in_real_d4 ;reg[C_DATA_WITH-1:0] S_data_in_real_d5 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d1 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d2 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d3 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d4 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d5 ;reg[C_DATA_WITH:0] S_data_out_real ;/// x1 X2reg[C_DATA_WITH:0] S_data_out_imag ;/// x1 X2// ============================================================// main code// ============================================================always @(posedge I_sys_clk) begin S_data_start_d1 <= I_data_start ; S_data_start_d2 <= S_data_start_d1 ; S_data_start_d3 <= S_data_start_d2 ; S_data_start_d4 <= S_data_start_d3 ; S_data_start_d5 <= S_data_start_d4 ; end/// 缓存数据always @(posedge I_sys_clk) begin S_data_in_real_d1 <= I_data_in_real ; S_data_in_real_d2 <= S_data_in_real_d1 ; S_data_in_real_d3 <= S_data_in_real_d2 ; S_data_in_real_d4 <= S_data_in_real_d3 ; S_data_in_real_d5 <= S_data_in_real_d4 ; S_data_in_imag_d1 <= I_data_in_imag ; S_data_in_imag_d2 <= S_data_in_imag_d1 ; S_data_in_imag_d3 <= S_data_in_imag_d2 ; S_data_in_imag_d4 <= S_data_in_imag_d3 ; S_data_in_imag_d5 <= S_data_in_imag_d4 ; end///always @(posedge I_sys_clk)if(S_data_start_d4)/// (x(n)-x(n+N/2)*W04 = (x(n)-x(n+N/2)begin S_data_out_real <= {S_data_in_real_d4[C_DATA_WITH-1],S_data_in_real_d4} - {S_data_in_real_d2[C_DATA_WITH-1],S_data_in_real_d2} ; S_data_out_imag <= {S_data_in_imag_d4[C_DATA_WITH-1],S_data_in_imag_d4} - {S_data_in_imag_d2[C_DATA_WITH-1],S_data_in_imag_d2} ; endelseif(S_data_start_d5)/// (x(n)-x(n+N/2)*W14 = (x(n)-x(n+N/2)*(-j) = (x(n+N/2)-x(n))*jbegin S_data_out_real <= {S_data_in_imag_d2[C_DATA_WITH-1],S_data_in_imag_d2} - {S_data_in_imag_d4[C_DATA_WITH-1],S_data_in_imag_d4} ; S_data_out_imag <= {S_data_in_real_d2[C_DATA_WITH-1],S_data_in_real_d2} - {S_data_in_real_d4[C_DATA_WITH-1],S_data_in_real_d4} ; endelse/// x(n)+x(n+N/2) x(0)+x(2)begin S_data_out_real <= {S_data_in_real_d2[C_DATA_WITH-1],S_data_in_real_d2} + {I_data_in_real[C_DATA_WITH-1],I_data_in_real} ; S_data_out_imag <= {S_data_in_imag_d2[C_DATA_WITH-1],S_data_in_imag_d2} + {I_data_in_imag[C_DATA_WITH-1],I_data_in_imag} ; end///delay 2clkcm_fft2_N2 #( .C_DATA_WITH (C_DATA_WITH+1 ) ) u0_cm_fft2_N2( .I_sys_clk (I_sys_clk ) ,/// 工作时钟 100M.I_data_start (S_data_start_d3|S_data_start_d5 ) ,/// 数据开始进入标志,与第一个数据对齐输入.I_data_in_real (S_data_out_real ) ,/// 数据输入,从start开始连续输入.I_data_in_imag (S_data_out_imag ) ,/// 数据输入,从start开始连续输入.O_data_start ( ) ,/// 数据开始输出标志与第一个数据对齐输出.O_data_out_real (O_data_out_real ) ,/// 数据输出,从start开始连续输出.O_data_out_imag (O_data_out_imag )/// 数据输出,从start开始连续输出); assign O_data_start = S_data_start_d5 ; endmodule

同理,进行8点FFT的计算,8点FFT的计算用到,W08=1,W18=0.707 - 0.707*1j,W28=-1j,W38=-0.707 - 0.707*1j,为了方便计算对其进行1024倍的量化,即1=1024,代码中使用W08=1024,W18=724 - 724*1j,W28=-1024j,W38=-724 - 724*1j。同时调用cmult复乘核进行复乘运算。代码如下:

// ============================================================// File Name: cm_fft2_N8// VERSION : V1.0// DATA : 2023/1/1// Author : FPGA干货分享// ============================================================// 功能:基2FFT N=8的数据处理// delay : 12clk// ============================================================`timescale 1ns/100ps module cm_fft2_N8 #( parameter C_DATA_WITH = 16 ) (inputwire I_sys_clk ,/// 工作时钟 100Minputwire I_data_start ,/// 数据开始进入标志,与第一个数据对齐输入inputwire [C_DATA_WITH-1:0] I_data_in_real ,/// 数据输入,从start开始连续输入inputwire [C_DATA_WITH-1:0] I_data_in_imag ,/// 数据输入,从start开始连续输入output wire O_data_start ,/// 数据开始输出标志与第一个数据对齐输出output wire [C_DATA_WITH+2:0] O_data_out_real ,/// 数据输出,从start开始连续输出output wire [C_DATA_WITH+2:0] O_data_out_imag/// 数据输出,从start开始连续输出);// ============================================================// 内部参数// ============================================================/// W08=1/// W18=0.707 - 0.707*1j/// W28=-1j/// W38=-0.707 - 0.707*1j// ============================================================// 变量// ============================================================regS_data_start_d1 ;regS_data_start_d2 ;regS_data_start_d3 ;regS_data_start_d4 ;regS_data_start_d5 ;regS_data_start_d6 ;regS_data_start_d7 ;regS_data_start_d8 ;regS_data_start_d9 ;regS_data_start_d10 ;regS_data_start_d11 ;regS_data_start_d12 ;reg[C_DATA_WITH-1:0] S_data_in_real_d1 ;reg[C_DATA_WITH-1:0] S_data_in_real_d2 ;reg[C_DATA_WITH-1:0] S_data_in_real_d3 ;reg[C_DATA_WITH-1:0] S_data_in_real_d4 ;reg[C_DATA_WITH-1:0] S_data_in_real_d5 ;reg[C_DATA_WITH-1:0] S_data_in_real_d6 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d1 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d2 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d3 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d4 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d5 ;reg[C_DATA_WITH-1:0] S_data_in_imag_d6 ;reg[11:0] S_Wn8_real ;reg[11:0] S_Wn8_imag ;reg[C_DATA_WITH:0] S_data_cut_real ;reg[C_DATA_WITH:0] S_data_cut_imag ; wire [C_DATA_WITH+13:0] S_data_multW_real ;/// X2wire [C_DATA_WITH+13:0] S_data_multW_imag ;/// X2reg[C_DATA_WITH:0] S_data_add_real ;/// x1reg[C_DATA_WITH:0] S_data_add_imag ;/// x1wire [C_DATA_WITH:0] S_data_out_real ;/// x1 X2wire [C_DATA_WITH:0] S_data_out_imag ;/// x1 X2// ============================================================// main code// ============================================================always @(posedge I_sys_clk) begin S_data_start_d1 <= I_data_start ; S_data_start_d2 <= S_data_start_d1 ; S_data_start_d3 <= S_data_start_d2 ; S_data_start_d4 <= S_data_start_d3 ; S_data_start_d5 <= S_data_start_d4 ; S_data_start_d6 <= S_data_start_d5 ; S_data_start_d7 <= S_data_start_d6 ; S_data_start_d8 <= S_data_start_d7 ; S_data_start_d9 <= S_data_start_d8 ; S_data_start_d10 <= S_data_start_d9 ; S_data_start_d11 <= S_data_start_d10; S_data_start_d12 <= S_data_start_d11; end/// 缓存数据always @(posedge I_sys_clk) begin S_data_in_real_d1 <= I_data_in_real ; S_data_in_real_d2 <= S_data_in_real_d1 ; S_data_in_real_d3 <= S_data_in_real_d2 ; S_data_in_real_d4 <= S_data_in_real_d3 ; S_data_in_real_d5 <= S_data_in_real_d4 ; S_data_in_real_d6 <= S_data_in_real_d5 ; S_data_in_imag_d1 <= I_data_in_imag ; S_data_in_imag_d2 <= S_data_in_imag_d1 ; S_data_in_imag_d3 <= S_data_in_imag_d2 ; S_data_in_imag_d4 <= S_data_in_imag_d3 ; S_data_in_imag_d5 <= S_data_in_imag_d4 ; S_data_in_imag_d6 <= S_data_in_imag_d5 ; end always @(posedge I_sys_clk) begin S_data_cut_real <= {S_data_in_real_d4[C_DATA_WITH-1],S_data_in_real_d4} - {I_data_in_real[C_DATA_WITH-1],I_data_in_real} ; S_data_cut_imag <= {S_data_in_imag_d4[C_DATA_WITH-1],S_data_in_imag_d4} - {I_data_in_imag[C_DATA_WITH-1],I_data_in_imag} ; end always @(*)if(S_data_start_d5) begin S_Wn8_real = 12'd1024 ; S_Wn8_imag = 12'd0 ; endelseif(S_data_start_d6) begin S_Wn8_real = 12'd724 ; S_Wn8_imag = -12'd724 ; endelseif(S_data_start_d7) begin S_Wn8_real = 12'd0 ; S_Wn8_imag = -12'd1024 ; endelsebegin S_Wn8_real = -12'd724 ; S_Wn8_imag = -12'd724 ; end/// 调用复乘 delay 6clkcmult # (.AWIDTH (C_DATA_WITH+1 ) , .BWIDTH (12 ) ) u0_cmult ( .clk (I_sys_clk ) , .ar (S_data_cut_real ) , .ai(S_data_cut_imag ) , .br(S_Wn8_real ) , .bi (S_Wn8_imag ) , .pr(S_data_multW_real ) , .pi(S_data_multW_imag ) );///always @(posedge I_sys_clk)/// x(n)+x(n+N/2) x(0)+x(4) ...begin S_data_add_real <= {S_data_in_real_d6[C_DATA_WITH-1],S_data_in_real_d6} + {S_data_in_real_d2[C_DATA_WITH-1],S_data_in_real_d2} ; S_data_add_imag <= {S_data_in_imag_d6[C_DATA_WITH-1],S_data_in_imag_d6} + {S_data_in_imag_d2[C_DATA_WITH-1],S_data_in_imag_d2} ; end assign S_data_out_real = (S_data_start_d7|S_data_start_d8|S_data_start_d9|S_data_start_d10) ? S_data_add_real : (S_data_multW_real[10+:(C_DATA_WITH+1)] + S_data_multW_real[9]) ; assign S_data_out_imag = (S_data_start_d7|S_data_start_d8|S_data_start_d9|S_data_start_d10) ? S_data_add_imag : (S_data_multW_imag[10+:(C_DATA_WITH+1)] + S_data_multW_imag[9]) ;///delay 5clkcm_fft2_N4 #( .C_DATA_WITH (C_DATA_WITH+1 ) ) u0_cm_fft2_N4( .I_sys_clk (I_sys_clk ) ,/// 工作时钟 100M.I_data_start (S_data_start_d7|S_data_start_d11 ) ,/// 数据开始进入标志,与第一个数据对齐输入.I_data_in_real (S_data_out_real ) ,/// 数据输入,从start开始连续输入.I_data_in_imag (S_data_out_imag ) ,/// 数据输入,从start开始连续输入.O_data_start ( ) ,/// 数据开始输出标志与第一个数据对齐输出.O_data_out_real (O_data_out_real ) ,/// 数据输出,从start开始连续输出.O_data_out_imag (O_data_out_imag )/// 数据输出,从start开始连续输出); assign O_data_start = S_data_start_d12 ; endmodule

输出倒序模块主要是用来实现下图中的地址转换,代码使用分布式RAM的乒乓操作,缓存两组数据信息,然后使用计数器的bit翻转达到输出倒序的目的。

图片

// ============================================================// File Name: cm_fft2_top// VERSION : V1.0// DATA : 2023/1/2// Author : FPGA干货分享// ============================================================// 功能:基2FFT 输出数据倒换// delay : fft N=8 delay8clk// ============================================================`timescale 1ns/100ps module cm_fft2_output_change #( parameter C_DATA_WIDTH = 16 , parameter C_ADDR_NUM = 4 )///fft点数为2**C_ADDR_NUM(inputwire I_sys_clk ,/// 工作时钟 100Minputwire I_data_start ,/// 数据开始进入标志,与第一个数据对齐输入inputwire [C_DATA_WIDTH-1:0] I_data_in_real ,/// 数据输入,从start开始连续输入inputwire [C_DATA_WIDTH-1:0] I_data_in_imag ,/// 数据输入,从start开始连续输入output wire O_data_start ,/// 数据开始输出标志与第一个数据对齐输出output wire [C_DATA_WIDTH-1:0] O_data_out_real ,/// 数据输出,从start开始连续输出,位宽按照最大能力输出output wire [C_DATA_WIDTH-1:0] O_data_out_imag/// 数据输出,从start开始连续输出,位宽按照最大能力输出);// ============================================================// 内部参数// ============================================================localparam C_DATA_NUM = 2**C_ADDR_NUM ;// ============================================================// 变量// ============================================================regS_pingpang_flag ;reg[C_ADDR_NUM:0] S_wr_addr ; wire S_wr_en ;reg[C_DATA_WIDTH*2-1:0] S_data_in ;reg[C_ADDR_NUM-1:0] S_rd_addr ; wire S_change_start ;reg[C_ADDR_NUM-1:0] S_data_cnt ;regS_start_d1 ;regS_start_d2 ;regS_start_d3 ;regS_pingpang_flag_rd ;// ============================================================// main code// ============================================================always @(posedge I_sys_clk)if(I_data_start) S_pingpang_flag <= ~S_pingpang_flag;elseS_pingpang_flag <= S_pingpang_flag ; always @(posedge I_sys_clk)if(I_data_start) S_wr_addr <= 'b0;elseif(S_wr_en) S_wr_addr <= S_wr_addr + 'd1;elseS_wr_addr <= S_wr_addr ; assign S_wr_en = ~S_wr_addr[C_ADDR_NUM]; always @(posedge I_sys_clk) S_data_in <={I_data_in_real,I_data_in_imag} ; assign S_change_start = ({S_wr_addr[C_ADDR_NUM-1],|S_wr_addr[C_ADDR_NUM-2:0]} == 2'b10); always @(posedge I_sys_clk)if(S_change_start) S_data_cnt <= 'd0;elseS_data_cnt <= S_data_cnt + 'd1; genvar j;generatefor(j=0;j< C_ADDR_NUM;j=j+1) begin:addr_change always @(posedge I_sys_clk) S_rd_addr[j] <= S_data_cnt[C_ADDR_NUM-j-1]; end endgenerate always @(posedge I_sys_clk)if(S_start_d1) S_pingpang_flag_rd <= S_pingpang_flag ;elseS_pingpang_flag_rd <= S_pingpang_flag_rd ; cm_dis_sdp_ram #( .C_DATA_WIDTH ( C_DATA_WIDTH*2 ) ,// Specify RAM data width.C_ADDR_WIDTH ( C_ADDR_NUM+1 ) ,// Specify RAM depth 2**C_ADDR_WIDTH.C_DELAY_NUM ( 1 ) ,// delay.INIT_FILE ("") )// Specify name/location of RAM initialization file if using one (leave blank if not)u0_cm_dis_sdp_ram( .I_addra ({S_pingpang_flag,S_wr_addr[C_ADDR_NUM-1:0]} ) ,// Write address bus, width determined from RAM_DEPTH.I_addrb ({S_pingpang_flag_rd,S_rd_addr} ) ,// Read address bus, width determined from RAM_DEPTH.I_dina (S_data_in ) ,// RAM input data.I_clka (I_sys_clk ) ,// Write clock.I_clkb (I_sys_clk ) ,// Read clock.I_wea (S_wr_en ) ,// Write enable.O_doutb ({O_data_out_real,O_data_out_imag} )// RAM output data); always @(posedge I_sys_clk) begin S_start_d1 <= S_change_start ; S_start_d2 <= S_start_d1 ; S_start_d3 <= S_start_d2 ; end assign O_data_start = S_start_d3 ; endmodule

将代码封装仿真tb如下,仿真调用三组数据,将输出结果与上文python代码的输出进行对比,证明代码正确。

// ============================================================// File Name: tb_cm_fft2_8_top// VERSION : V1.0// DATA : 2023/1/2// Author : FPGA干货分享// ============================================================// 功能:基2FFT N=8的数据处理// delay : clk// ============================================================`timescale1ns/100ps module tb_cm_fft2_8_top ; parameter C_DATA_WITH_IN =16; parameter C_DATA_WITH_OUT =19;///要根据FFT点数合理设置parameter C_N_NUM =8;///fft点数 2,4,8,16...reg I_sys_clk ='d0;/// 工作时钟 100Mreg I_data_start ='d0;/// 数据开始进入标志,与第一个数据对齐输入reg [C_DATA_WITH_IN-1:0] I_data_in_real ='d0;/// 数据输入,从start开始连续输入reg [C_DATA_WITH_IN-1:0] I_data_in_imag ='d0;/// 数据输入,从start开始连续输入wire O_data_start ;/// 数据开始输出标志与第一个数据对齐输出wire [C_DATA_WITH_OUT-1:0] O_data_out_real ;/// 数据输出,从start开始连续输出,位宽按照最大能力输出wire [C_DATA_WITH_OUT-1:0] O_data_out_imag ;/// 数据输出,从start开始连续输出,位宽按照最大能力输出always #1I_sys_clk = ~I_sys_clk; initial begin repeat(100) @(posedge I_sys_clk); @(posedge I_sys_clk); I_data_start <=1'b1; I_data_in_real <=16'd1024; I_data_in_imag <=16'd0; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <=16'd0; I_data_in_imag <=16'd0; repeat(6) @(posedge I_sys_clk); @(posedge I_sys_clk); I_data_start <=1'b1; I_data_in_real <=16'd0; I_data_in_imag <=16'd1024; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <=16'd724; I_data_in_imag <=16'd724; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <=16'd1024; I_data_in_imag <=16'd0; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <=16'd724; I_data_in_imag <= -16'd724; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <=16'd0; I_data_in_imag <= -16'd1024; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <= -16'd724; I_data_in_imag <= -16'd724; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <= -16'd1024; I_data_in_imag <=16'd0; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <= -16'd724; I_data_in_imag <=16'd724;//@(posedge I_sys_clk); I_data_start <=1'b1; I_data_in_real <=16'd0; I_data_in_imag <=16'd1024; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <=16'd1024; I_data_in_imag <=16'd0; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <=16'd0; I_data_in_imag <= -16'd1024; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <= -16'd1024; I_data_in_imag <=16'd0; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <=16'd0; I_data_in_imag <=16'd1024; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <=16'd1024; I_data_in_imag <=16'd0; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <=16'd0; I_data_in_imag <= -16'd1024; @(posedge I_sys_clk); I_data_start <=1'b0; I_data_in_real <= -16'd1024; I_data_in_imag <=16'd0; end cm_fft2_8_top #( .C_DATA_WITH_IN (C_DATA_WITH_IN ) , .C_DATA_WITH_OUT (C_DATA_WITH_OUT ) , .C_N_NUM (C_N_NUM ) ) cm_fft2_8_top ( .I_sys_clk (I_sys_clk ) ,/// 工作时钟 100M.I_data_start (I_data_start ) ,/// 数据开始进入标志,与第一个数据对齐输入.I_data_in_real (I_data_in_real ) ,/// 数据输入,从start开始连续输入.I_data_in_imag (I_data_in_imag ) ,/// 数据输入,从start开始连续输入.O_data_start (O_data_start ) ,/// 数据开始输出标志与第一个数据对齐输出.O_data_out_real (O_data_out_real ) ,/// 数据输出,从start开始连续输出.O_data_out_imag (O_data_out_imag )/// 数据输出,从start开始连续输出); endmodule

输入信号

图片

输出信号:

图片

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1619

    文章

    21467

    浏览量

    597794
  • 算法
    +关注

    关注

    23

    文章

    4527

    浏览量

    91748
  • 仿真
    +关注

    关注

    50

    文章

    3936

    浏览量

    132805
  • 代码
    +关注

    关注

    30

    文章

    4637

    浏览量

    67604
  • python
    +关注

    关注

    53

    文章

    4747

    浏览量

    83913
收藏 人收藏

    评论

    相关推荐

    【NUCLEO-F412ZG试用体验】ARM的FFT使用及误差分析

    的数字信号,就可以做 FFT变换了。N个采样点数据,在经过 FFT之后,就可以得到N个点的 FFT结果。对于快速 FFT算法,有
    发表于12-16 20:31

    modelsim仿真fft

    modelsim 仿真 fft,自己用 Verilog写的程序,我给一个正弦波,发现 仿真后的结果是四个尖峰,按道理说应该是两个尖峰相互对称,我是512点的。为什么中间多出两个尖峰,不知道
    发表于01-20 08:53

    Verilog代码书写规范

    Verilog 代码书写规范 本规范的目的是提高书写 代码的可读性、可修改性、可重用性,优化 代码综合和 仿真的结果,指导设计工程师使用
    发表于04-15 09:47 106次下载

    FFTVerilogRTL

    FFT VerilogRTL
    发表于07-08 15:55 41次下载

    FFT变换

      4.1 引言   4.2 2FFT算法   4.3 进一步减少运算量的措施   4.4 分裂 FFT算法   4.5 离散哈特莱变换(DHT)
    发表于08-11 16:50 0次下载

    fpga实现jpegVerilog代码

    本站提供的fpga 实现jpeg Verilog代码资料,希望能够帮你的学习。
    发表于05-27 15:09 200次下载

    基于FPGA高精度浮点运算器的FFT设计与仿真

    提出一种 2FFT的FPGA方法,完成了基于FPGA高精度浮点运算器的 FFT的设计。利用VHDL语言描述了蝶形运算过程及地址产生单元,其 仿真波形基本能正确的表示输出结果。
    发表于12-23 14:24 46次下载
    基于FPGA高精度浮点运算器的<b class='flag-5'>FFT</b>设计与<b class='flag-5'>仿真</b>

    八选一多路选择器Verilog代码仿真结果MUX_8

    八选一多路选择器 Verilog 代码仿真结果(modelsim 仿真
    发表于03-28 15:27 32次下载

    快速傅里叶变换FFT的C程序代码实现

    本文为您讲解快速傅里叶变换 FFT的C语言程序 代码 实现的具体方法,C编程需要解决的问题及 FFT计算结果验证。
    发表于10-08 16:38 6.1w次阅读
    快速傅里叶变换<b class='flag-5'>FFT</b>的C程序<b class='flag-5'>代码</b><b class='flag-5'>实现</b>

    可配置FFTIP核的实现及基础教程

    针对 FFT算法基于FPGA 实现可配置的IP核。采用基于流水线结构和快速并行算法 实现了蝶形运算和4k点 FFT的输入点数、数据位宽、分解 自由配
    发表于11-18 06:32 7728次阅读
    可配置<b class='flag-5'>FFT</b> IP核的<b class='flag-5'>实现</b>及基础教程

    如何使用IcarusVerilog+GTKWave来进行verilog文件的编译和仿真

    Windows+Linux+MacOS,并且源 代码开源。通过tb文件可以生成对应的 仿真波形数据文件,通过GTKWave可以查看 仿真波形图,支持将 Verilog转换为VHDL文件。 1.
    的头像 发表于07-27 09:16 5002次阅读
    如何使用Icarus <b class='flag-5'>Verilog</b>+GTKWave来进行<b class='flag-5'>verilog</b>文件的编译和<b class='flag-5'>仿真</b>

    使用Matlab和Verilog实现fibonacci序列包括源代码和testbench

    使用Matlab和 Verilog 实现fibonacci序列包括源 代码和testbench(电源技术论坛app)-使用Matlab和 Verilog 实现
    发表于09-16 14:41 13次下载
    使用Matlab和<b class='flag-5'>Verilog</b><b class='flag-5'>实现</b>fibonacci序列包括源<b class='flag-5'>代码</b>和testbench

    Vivado:ROM和RAM的verilog代码实现

    本文主要介绍ROM和RAM 实现verilog 代码版本,可以借鉴参考下。
    的头像 发表于05-16 16:57 1255次阅读

    2FFT的算法推导及python仿真

    FFT的算法推导主要用到旋转因子的周期性、对称性和可约性。
    的头像 发表于06-02 12:38 1603次阅读
    <b class='flag-5'>基</b><b class='flag-5'>2FFT</b>的算法推导及python<b class='flag-5'>仿真</b>

    Verilog代码封装后门访问

    关于 仿真里的后门访问,之前的文章《三分钟教会你SpinalHDL 仿真中的后门读写》中有做过介绍,其针对的都是针对以SpinalHDL中的 代码进行的后门访问。今天来看看当封装了 Verilog
    的头像 发表于07-15 10:22 729次阅读
    <b class='flag-5'>Verilog</b><b class='flag-5'>代码</b>封装后门访问