门户网站等保二级建设方案wordpress 后台代码
本文介绍了Vidado中FFT IP核的使用,具体内容为:调用IP核>>配置界面介绍>>IP核端口介绍>>MATLAB生成测试数据>>测试verilogHDL>>TestBench仿真>>结果验证>>FFT运算。
1、调用IP核
该IP核对应手册pg109_xfft.pdf,首先按照图片找到IP核:
 
 2、配置界面介绍
本小节主要介绍Fast Fourier Transform9.1这个IP核配置界面的一些选项:
第1页:Configuration
 图1
表1 Configuration界面介绍
Configuration  | ||
Number of Channels  | 变换通道,可以选择多通道,实现多帧数据同时进行FFT运算  | |
Transform Length  | FFT变换长度,如果选择了最下面的‘run time configurable transform length’,则该参数是FFT变化的最大长度,一般不选  | |
Architecture Configuration  | Target Clock Frequency(MHz)  | 配置系统时钟  | 
Target Data Throughput(MSPS)  | 数据吞吐量  | |
Architecture Choice  | Automatically Select  | 自动选择所需要的,FFT变化架构  | 
Pipelined, Streaming I/O  | 流水线结构,处理速度最快,但消耗资源多(只要将数据组成长序列输入,核就会按照FFT点数连续输出变换结果)  | |
Radix-4, Burst I/O  | 基4 I/O突发结构  | |
Radix-2, Burst I/O  | 基2 I/O突发结构  | |
Radix-2 lite, Burst I/O  | 基2 lite I/O突发结构  | |
Run Time Configuration Transform Length  | 该选项可以在FFT变换中通过设置s_axis_config_tdata中 NFFT字段的长度来改变FFT变化的长度  | |
第2页:Implementation
 图2
表2 Implementation界面介绍
Implementation  | ||
Data Format  | Fixed Point  | 定点全精度  | 
Floating Point  | 定点缩减位宽  | |
Scaling Options  | Block Floating Point  | 不管输入的格式如何,FFT变化内部都采用浮点,会根据每一级的数据情况自动缩放。 这个模式的输入输出位宽一致,便于调用  | 
Scaled  | 在s_axis_config_data中会有相应的字段配置缩放因子.每一级别包含2个stage ,2个bit 表示一级缩放,一般0-3可选,如果log(NFFT)不是2的倍数,则最高一级的缩放只能在0-1之间选取  | |
Unscaled  | 不用担心变化过程中会出现溢出,但是输入是32bit的话,输出是64bit  | |
Rounding Modes  | Convergent Rounding  | 采用四舍五入输出数据(会使用更多的位宽来实现,增加转换速度和使用资源)  | 
Trancation  | 采用截位输出数据  | |
Precision Options  | Input Data Width  | 输入数据的位宽  | 
Phase Factor Width  | 输入数据相位因子宽度  | |
Control Signals  | ACLKEN  | 时钟使能  | 
ARESETn(active low)  | 复位信号  | |
Output Ordering Options  | 输出位序选项  | |
Output Ordering  | Bit/Digit Reversed Order  | 逆序输出  | 
Natural Order  | 顺序输出  | |
Optional Output Fields  | XK_INDEX  | 勾选表示给出输出索引  | 
OVFLO  | 变换中溢出的指示信号  | |
Throttle Sheme  | Non Real Time  | 输出不遵循真实时间  | 
Real Time  | 输出遵循真实时间  | |
第3页:Detailed Implementation
 图3
表3 Detailed Implementation
Detailed Implementation  | ||
Memory Options  | 存储器选项  | |
Data  | Block RAM  | 突发I/O架构:块RAM或分布式RAM均可用于数据和相位因子存储; 流水线流I/O:数据部分存储在块RAM部分存储在分布式RAM上,因此这两项都无法配置  | 
Distributed RAM  | ||
Phase Factors  | Block RAM  | |
Distributed RAM  | ||
Number of stages using Block RAM for Data and Phase Factors  | 选择块RAM的级数, 一般用不到默认即可  | |
Reorder Buffer  | Block RAM  | 流水线模式可选则配置,一般默认即可  | 
Distributed RAM  | ||
Optimize Block RAM Count Using Hybrid Memories  | 一种优化存储的方式,一般不用  | |
Optimize Options  | 优化选项  | |
Complex Multipliers 
  | Use 3-multiplier structure  | 使用更多的DSP切片优化运算  | 
Use 4-multiplier structure  | 比“3-multiplier”运算更快, 使用资源更多  | |
Use CLB Logic  | 一般用在性能要求较低的设计中  | |
Butterfly Arithmetic  | Use CLB Logic  | 切片逻辑构造蝶形运算  | 
Use XtremeDsp Slices  | 使用DSP切片的蝶形运算,强制使用DSP切片内部的加/减法器  | |
3、IP核端口配置
根据上述配置界面的介绍,下面以64点IFFT为例子,总结了使用IP核时所需的端口配置,如表4所示,需要注意的是表4中没有涉及的部分按照IP核的默认配置即可:
表4 64点IFFT运算IP核的设置表汇总
Configuration  | ||
Number of Channels  | 1  | |
Transform Length  | 64  | |
Architecture Configuration  | Target Clock Frequency(MHz)  | 50  | 
Target Data Throughput(MSPS)  | 50  | |
Target  | Pipelined, Streaming I/O  | |
Implementation  | ||
Data Format  | Fixed Point  | |
Scaling Options  | Scaled  | |
Rounding Modes  | Truncation  | |
Precision Options  | Input Data Width  | 16  | 
Phase Factor Width  | 16  | |
Control Signals  | ACLKEN  | 勾选  | 
Output Ordering Options  | Output Ordering  | Natural Order  | 
Optional Output Fields  | XK_INDEX  | |
Throttle Sheme  | Non Real Time  | |
Detailed Implementation  | ||
该界面配置全部默认  | ||
配置完成之后IP核的端口图如下:
 图4 64点IFFT核端口图
按照下面图找到例化原语:
 图5
打开.veo后缀的文件找到例化原语:
 图6
对例化语句的介绍见表5,其中L表示IFFT/FFT的点数。
表5 例化原语介绍
端口名称  | IN/OUT  | 勾选  | 
aclk  | IN  | 系统时钟  | 
aclken  | IN  | 时钟使能  | 
s_axis_config_tdata  | IN  | 控制输入模式,进行fft/ifft以及衰减因子的设置,FWD_INV = 1做 fft,FWD_INV = 0做ifft  | 
s_axis_config_tvalid  | IN  | 拉高两个时钟周期之后,将端口s_axis_data_tvalid和s_axis_data_tready拉高  | 
s_axis_config_tready  | OUT  | s_axis_config_tvalid拉高两个时钟周期后,该口给1输出;若干个时钟周期后,自动归零  | 
s_axis_data_tdata  | IN  | 将数据输入进行FFT运算结果  | 
s_axis_data_tvalid  | IN  | 当s_axis_data_tready高电平后,将s_axis_data_tvalid拉高L个周期,输入L个数据进行fft;L是FFT的点数  | 
s_axis_data_tready  | OUT  | aresetn拉高两个时钟周期后,该口给1输出;此时ip核初始化完成,可进行数据输入  | 
s_axis_data_tlast  | IN  | 数据输入完毕后拉高,停止数据输入  | 
m_axis_data_tdata  | OUT  | 高位为虚部,低位为实部  | 
m_axis_data_tuser  | OUT  | 输出fft的地址值,输出值*fs/L为对应频点  | 
m_axis_data_tvalid  | OUT  | 当ifft结果输出时拉高,输出L个点的数据后拉低  | 
m_axis_data_tready  | IN  | 需保持高电平,保证FFT单元处在计算模式,并且能够输出结算结果  | 
m_axis_data_tlast  | OUT  | 当fft结果输出到最后一个结果时拉高, 紧接着下一个时钟就拉低  | 
event_frame_started  | OUT  | 当出现新的计算时给出  | 
event_tlast_unexpected  | OUT  | 当数据输入完毕而s_axis_data_tlast,没有拉高时给出  | 
event_tlast_missing  | OUT  | 但数据输入完毕之前s_axis_data_tlast,就拉高时给出  | 
event_status_channel_halt  | OUT  | 当核不能将数据正常输出给状态通道时给出  | 
event_data_in_channel_halt  | OUT  | 但核当前请求数据而数据没输入时给出  | 
event_data_out_channel_halt  | OUT  | 当核不能将数据正常输出给数据通道时给出  | 
需要说明的是,需要配置的端口有,1)aclk;2)aclken;3)s_axis_config_tdata ;4)s_axis_config_tvalid ;5)s_axis_config_tready;6)s_axis_data_tdata;7)s_axis_data_tvalid;8)s_axis_data_tready;9)m_axis_data_tdata;10)m_axis_data_tuser;11)m_axis_data_tready;12)m_axis_data_tlast
4、MATLAB生成测试数据
本次测试只需要使用TestBench验证即可,需要生成.txt后缀的文件,产生IFFT核的输入数据,主要程序为:
%% 该.m文件用来生成介绍IFFT核的数据,具体为64点的IFFT  16QAM
clear
close all
clc
rng default  %产生固定数值的随机数据
%% 基于符号算法的目标距离和速度探测
%% 定义基本参数
Ns=1;                                                   %符号数
Nc=64;                                                  %子载波数
M=16;                                                   %调制方式
bit_num=log2(M);                                        %一个码组中的码元个数
bit=randi([0 1],Nc*Ns*bit_num,1);                       %产生比特
norm=1/sqrt(10);                                        %16qam 归一化因子
%% 16qam
bit_convert=(reshape(bit,bit_num,length(bit)/bit_num))';%二进制数据流按照调制的方式分成不同码元
data_2_to_10=bi2de(bit_convert,'left-msb');             %将每四位数据转换为十进制数
maxtix=reshape(data_2_to_10,Nc,Ns);
bit_mo=norm*qammod(data_2_to_10,M);
a_nm=reshape(bit_mo,Nc,Ns);
%% 发送端IFFT调制
IFFT_OUT=ifft(a_nm,64);
%%  数据保存为.txt文件echo_real=real(a_nm);echo_imag=imag(a_nm);echo1_real=quantizer([16 11]);echo1_imag=quantizer([16 11]);fid_echo=fopen('C:\Users\15865\Desktop\FFT_IP_core_64point\IFFT_IP_core_64point_exam.txt','wt');for j=1:Nsecho2_real=num2bin(echo1_real,echo_real(:,j));echo2_imag=num2bin(echo1_imag,echo_imag(:,j));for i=1:Ncimag_real_echo=[echo2_imag(i,:),echo2_real(i,:)];fwrite(fid_echo,imag_real_echo);fprintf(fid_echo,'\n');endend
fclose(fid_echo); 图中程序功能是生成了一段包含64个复数数据的数组,并将每个复数数据用16表示实部16位表示虚部共生成32位二进制数,最后将这组数据保存为.txt后缀文件。
5、测试verilog HDL
根据前文的配置编写一个简单的测试.v文件测试64点数据的IFFT运行结果,主要程序如下:
`timescale 1ns / 1ps
module IFFT_introduction(input        clk,input        rst_n,input        ifft_valid,input [31:0] data_in,
//        input        last,output        s_config_tready,output [31:0] m_data_tdata,output        s_data_tready,output [7:0]  m_data_tuser,output        m_data_tvalid,output        m_data_tlast);FFT_IP_core_64point ifft_u0(.aclk(clk),                                      // input wire aclk.aclken(rst_n),                                  // input wire aclken.s_axis_config_tdata(8'd0),                      // input wire [7 : 0] s_axis_config_tdata.s_axis_config_tvalid(1'b1),                     // input wire s_axis_config_tvalid.s_axis_config_tready(s_config_tready),          // output wire s_axis_config_tready.s_axis_data_tdata(data_in),                     // input wire [31 : 0] s_axis_data_tdata.s_axis_data_tvalid(ifft_valid),                 // input wire s_axis_data_tvalid.s_axis_data_tready(s_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_data_tdata),                // output wire [31 : 0] m_axis_data_tdata.m_axis_data_tuser(m_data_tuser),                // output wire [7 : 0] m_axis_data_tuser.m_axis_data_tvalid(m_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_data_tlast)                 // output wire m_axis_data_tlast
);wire [15:0] ifft_64point_out_RE,ifft_64point_out_IM;
//  assign RE={{4{m_data_tdata[15]}},m_data_tdata[15:4]};//IFFT归一化处理,除Nfft
//  assign IM={{4{m_data_tdata[39]}},m_data_tdata[39:28]};assign ifft_64point_out_IM=m_data_tdata[31:16]; //虚部assign ifft_64point_out_RE=m_data_tdata[15:0];  //实部 endmodule
 这段程序调用了FFT IP核的例化原语,并将部分接口作为函数的输入和输出,方便TestBench调用。
6、TestBench仿真
主要程序如下:
`timescale 1ns / 1ps
module ifft_tb();
reg        clk;             //系统时钟
reg        rst_n;           //复位信号,低有效
reg        ifft_valid;      //数据有效位,指示输入数据有效
reg [31:0] data_in;         //输入数据wire s_config_tready;       
wire [31:0] m_data_tdata;   
wire s_data_tready;         
wire [7:0] m_data_tuser;    
wire m_data_tvalid;         
wire m_data_tlast;IFFT_introduction u0(    //例化.v文件.clk(clk),.rst_n(rst_n),.ifft_valid(ifft_valid),.data_in(data_in),.s_config_tready(s_config_tready),.m_data_tdata(m_data_tdata),.s_data_tready(s_data_tready), .m_data_tuser(m_data_tuser),.m_data_tvalid(m_data_tvalid),.m_data_tlast(m_data_tlast)
);
reg [31:0] mem [63:0];
initial begin       //$readmemb Vivado内置函数调用.txt文件$readmemb("C:/Users/15865/Desktop/FFT_IP_core_64point/IFFT_IP_core_64point_exam.txt",mem);clk=0;rst_n=0;#1000;rst_n=1;#10_000;$stop;
end
always #10 clk<=~clk;    //50MHz
reg [6:0] count;        
//计数
always@(posedge clk or negedge rst_n) beginif(!rst_n) count<='d0;else if(count<='d63)count<=count+1'b1;elsecount<='dz;
end
// 产生信号和数据
always@(posedge clk or negedge rst_n) beginif(!rst_n) beginifft_valid<='d0;data_in<='d0;endelse if(count>='d0 && count<='d63) beginifft_valid<=1;data_in<=mem[count];endelse beginifft_valid<=1'b0;data_in<='d0;end
end
endmodule
  7、Modelsim结果与MATLAB输出结果验证
本节将验证Modelsim和MATLAB输出结果的一致性,并简单介绍Modelsim输出结果向MATLAB数据的转换。
Modelsim 输出结果如下图:
 图10
由于数据有64个而这里验证前三个中间三个和后三个的方式验证Modelsim数据和MATLAB数据正确性:
表6数据验证
MATLAB  | 序号  | Modelsim  | 序号  | 
0.0791+0.791i  | 1  | 0.0788+0.0788i  | 1  | 
0.1504-0.1122i  | 2  | 0.1503-0.1122i  | 2  | 
-0.0336+0.2315i  | 3  | -0.0337+0.2314i  | 3  | 
-0.1444-0.0422i  | 31  | -0.1444-0.0422i  | 31  | 
-0.1533+0.1128i  | 32  | -0.1553+0.1128i  | 32  | 
-0.0395+0.0791i  | 33  | -0.0395+0.0790i  | 33  | 
0.0992-0.1690i  | 62  | 0.0992-0.1689i  | 62  | 
-0.1036+0.0314i  | 63  | -0.1036+0.0314i  | 63  | 
-0.1168-0.1773i  | 64  | -0.1167-0.1773i  | 64  | 
需要注意的是,Modelsim输出的结果并不是小数,而是忽略了小数点的整数,要想获得和MATLAB类似的浮点数,需要我们将输出结果变换,这里以Modelsim输出的最后一个数为例(即表6中序号64),可见图11。
 图11
对于该结果需要我们将输出结果除以2^(a+ b),a为用以表示小数的位宽数,本文中为11,b为FFT点数的2次幂幂值,本文为6,因此对于每一个Modelsim的输出结果都需要除以2^17,这里实部-15302/2^17=-0.1167,虚部-23234/2^17=-0.1773。
从表6中数据可以看出,IFFT 核执行的运算和MATLAB的运算结果十分接近,验证成功。
8、FFT运算
与IFFT运算类似,配置不用更改只需将第5小节程序中,s_axis_config_tdata端口配置改为8’d1即可,其他无需变动。
参考:
https://blog.csdn.net/duanchangrenhit/article/details/109639454
