vivadoIP核FFT的使用

FFT配置讲解

*在这里插入图片描述


(1)表示几个通道,这里我采用1024个点不同频率的正弦波。采用一通道
(2)表示通道点的个数。
(3)给FFT作用的时钟频率
(4)从上到下。算法越来越简单。

*在这里插入图片描述
(1)输入数据的格式,我选择的为定点,还有浮点数据格式。
(2)选择算法类似上一张图的第四点。来考虑数据溢出。
(3)类似四舍五入对数据进行截断,进行判断的。
(4)输入数据的位宽。
(5)低电平复位
(6)有正序和倒序输出。我选择的正序。
(7)这个就是non real time 更加浪费资源, real time 节约资源。但是好处是non real time 对于输入时序要求低。

ip口生成如下


```c
xfft_0 xfft_0_U0 (
  .aclk                 (i_clk                  ),                                                // input wire aclk
  .aresetn              (~i_rst                 ),                                          // input wire aresetn

  .s_axis_config_tdata  (s_axis_config_tdata    ),                  // input wire [7 : 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,w_data}         ),                      // input wire [31 : 0] s_axis_data_tdata
  .s_axis_data_tvalid   (w_valid                ),                    // input wire s_axis_data_tvalid
  .s_axis_data_tready   (w_ready                ),                    // output wire s_axis_data_tready 表示已经准备接收好数据
  .s_axis_data_tlast    (w_last                 ),                      // input wire s_axis_data_tlast

  .m_axis_data_tdata    (w_fft_result           ),                      // output wire [63 : 0] m_axis_data_tdata
  .m_axis_data_tvalid   (w_fft_valid            ),                    // output wire m_axis_data_tvalid
  .m_axis_data_tready   (1                      ),                    // input wire m_axis_data_tready
  .m_axis_data_tlast    (                       ),                      // output wire m_axis_data_tlast

  .event_frame_started  (),                  // output wire event_frame_started
  .event_tlast_unexpected(),            // output wire event_tlast_unexpected
  .event_tlast_missing  (),                  // output wire event_tlast_missing
  .event_status_channel_halt(),      // output wire event_status_channel_halt
  .event_data_in_channel_halt(),    // output wire event_data_in_channel_halt
  .event_data_out_channel_halt()  // output wire event_data_out_channel_halt
);

>解释:**代码的3,4,5类似握手信号,说来了数据,是有效的,赶快输出一下高电平。**
>代码的6,7,8,9表示输入的数据,其中高16为没虚数输入的0。低位输出的数。表示数据来了一直有效,输出数据接收好了。w_last表示输入完的最后一位数据。
>   10  11  12结果。需要等待输入数据完成,等待fft计算完成才会显示。表示输出数据是有效的。1表示随时准备接收数据


> 
**DDS模块**



module DDS_Gen#(
    parameter       P_NUMBER = 1024 ,
    parameter       P_WIDTH  = 16   
)(
    input                   i_clk           ,
    input                   i_rst           ,

    output [P_WIDTH - 1:0]  o_data          ,
    output                  o_valid         ,
    output                  o_last          ,
    input                   i_ready          

);

reg  [P_WIDTH - 1:0]            ro_data                 ;
(* ram_style = "block" *)
reg  [P_WIDTH - 1:0]            r_ram[0 : P_NUMBER - 1] ;
reg  [$clog2(P_NUMBER) -1 :0]   r_ram_addr              ;
reg                             ro_valid                ; 
reg                             ro_last                 ; 

assign o_data = ro_data                                 ;
assign o_valid = ro_valid                               ;
assign o_last  = ro_last                                ;


initial begin
    $readmemh("fft_data.dat",r_ram,0,P_NUMBER - 1);
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        ro_data <= 'd0;
    else 
        ro_data <= r_ram[r_ram_addr];
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_ram_addr <= 'd0;
    else if(ro_valid && r_ram_addr == P_NUMBER - 1)
        r_ram_addr <= r_ram_addr;
    else if((r_ram_addr == 0 && i_ready) || ro_valid)
        r_ram_addr <= r_ram_addr + 1;
    else
        r_ram_addr <= r_ram_addr;
end

always@(posedge i_clk)
begin
    if(i_rst)
        ro_valid <= 'd0;
    else if(ro_last && ro_valid && i_ready)
        ro_valid <= 'd0;
    else if(r_ram_addr == 0 && i_ready)
        ro_valid <= 'd1;
    else 
        ro_valid <= ro_valid;
end

always@(posedge i_clk)
begin
    if(i_rst)
        ro_last <= 'd0;
    else if(ro_last && ro_valid && i_ready)
        ro_last <= 'd0;
    else if(ro_valid && r_ram_addr == P_NUMBER - 1)
        ro_last <= 'd1;
    else    
        ro_last <= ro_last;
end

代码先生成一个ram,然后写入数据,读出数据。假设 P_NUMBER 是 16。
clog2(16) 的结果是 4,因为 2^4 = 16。
[$clog2(16) - 1 : 0] 变成 [3 : 0],表示 r_ram_addr 的位宽是 4 位(从 3 到 0)。
这里就是算有多少二进制,比如16需要4位1111表示。类似十进制转换为二进制。
(* ram_style = “block” *) 调用了系统原语。
$readmemh(“fft_data.dat”,r_ram,0,P_NUMBER - 1);读取1024个数,数据由matlab生成。
下面的就是根据地址读取数据,读取数据的时候有一个有效信号,读取完了顺便有一个last标志信号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值