FFT_IP核原理框图
引脚定义:
aclk: 上升沿有效
aclken: 高电平时钟使能(可选)
aresetn: Active-Low同步清除(可选,始终优先于aclken)。需要两个周期的最小有效脉冲。
s_axis_config_tvalid:配置频道的TVALID。 由外部主设备发出信号,表明它能够提供数据。
s_axis_config_tready: TREADY作为配置通道。 核心声明表示已准备好接受数据。
s_axis_config_tdata: TDATA用于配置通道。携带配置信息:CP_LEN,FWD / INV,NFFT和SCALE_SCH。 请参阅运行时间转换配置。
s_axis_data_tvalid: 数据输入通道的TVALID。 由外部主设备用来表示它能够提供数据。
s_axis_data_tready: 数据输入通道的TREADY。核心用它来表示已经准备好接受数据。
s_axis_data_tdata: TDATA为数据输入通道。 载入未处理的采样数据:XN_RE和XN_IM。 请参阅数据输入通道。
s_axis_data_tlast: 数据输入通道的TLAST。 在框架的最后一个样本上由外部主设备声明。 除了生成事件event_tlast_unexpected和event_tlast_missing事件之外,核心不使用这个事件。
m_axis_data_tvalid: 数据输出通道的TVALID。 核心声明表示能够提供样本数据。
m_axis_data_tready: 数据输出通道的TREADY。由外部从设备断言,表示已准备好接受数据。 仅以非实时模式呈现。
m_axis_data_tdata: TDATA为数据输出通道。载入处理后的样本数据XK_RE和XK_IM。
m_axis_data_tuser: 用于数据输出通道的TUSER。携带附加的每个样本信息,例如XK_INDEX,OVFLO和BLK_EXP。
m_axis_data_tlast: 数据输出通道的TLAST。在框架的最后一个样本上由核心声明。
m_axis_status_tvalid: 状态通道的TVALID。核心声明表示它能够提供状态数据。
m_axis_status_tready: TREADY用于状态通道。由外部从设备断言,表示已准备好接受数据。 仅以非实时模式呈现。
m_axis_status_tdata: TDATA的状态通道。携带状态数据:BLK_EXP或OVFLO.See状态通道。
event_frame_started: 当核开始处理一个新的帧时声明。请参阅event_frame_started。
event_tlast_unexpected: 当内核在不是帧中最后一个数据采样的s_axis_data_tlast为高电平时触发。请参阅event_tlast_unexpected。
event_tlast_missing: 在帧的最后一个数据样本上s_axis_data_tlast为低时断言。 请参阅event_tlast_missing。
event_fft_overflow: 在从数据输出通道卸载的数据样本中发现溢出时断言。 只有当溢出是一个有效的选项时才出现。 请参阅event_fft_overflow。
event_data_in_channel_halt: 内核从数据输入通道请求数据并且没有可用时声明。 请参阅event_data_in_channel_halt。
event_data_out_channel_halt: 当内核尝试将数据写入数据输出通道并且无法执行时声明。 仅以非实时模式呈现。 请参阅event_data_out_channel_halt。
event_status_channel_halt: 当内核尝试将数据写入状态通道并且无法执行时断言。 仅以非实时模式呈现。 请参阅event_status_channel_halt。
IP核测试调用过程:
第一步:添加IP核(通过在project manager中的IP Catalog中添加IP核)
第二步:在Hierarchy->simulation source目录下添加测试代码
运行仿真即可
需注意:
configuration:选择通道时可选择1个通道、传输长度为数据长度。
implementation:可选择数据类型和unscaled选项。
Detailed Implementation:可不用配置。
切记:
对IP核进行配置时,不可将IP核在初始化后直接将数据类型配置为浮数,需从定点->浮数按部就班配置,否则直接将IP核第一次配置为浮数型会失败,无法生成框架代码。。
配置示例1:(定数)
number of channel :1
Transform length : 8
data Format : fixed point
scaling options : unsclaed
rounding modes : truncation
input data width : 16
phase factor width : 16
**代码配置:(测试代码中)
只做重要部分解释:**
module fft_test_bench( );
reg aclk;
reg s_axis_config_tvalid;
reg s_axis_data_tvalid;
reg s_axis_data_tlast;
reg m_axis_data_tready;
reg [7:0] s_axis_config_tdata;
reg [31: 0] s_axis_data_tdata;
// Outputs
wire s_axis_config_tready;
wire s_axis_data_tready;
wire m_axis_data_tvalid;
wire m_axis_data_tlast;
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;
wire [47 : 0] m_axis_data_tdata;
reg[15:0] mem0_re[0:7];
reg[15:0] mem1_re[0:7];
reg[15:0] mem2_re[0:7];
initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus0_24bit.dat",mem0_re);
initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus1_24bit.dat",mem1_re);
initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus2_24bit.dat",mem2_re);
// reg[7:0] op_sample= 0;
// reg op_sample_first = 1;
// reg[7:0] ip_frame=0;
// reg[7:0] op_frame=0;
integer i;
// generate clk
always #5 aclk =! aclk;
// Instantiate the Unit Under Test (UUT)
xfft_1 uut (
.aclk(aclk), // input wire aclk
.s_axis_config_tdata(s_axis_config_tdata), // 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(s_axis_data_tdata), // input wire [95 : 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 [95 : 0] m_axis_data_tdata
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tready(m_axis_data_tready), // 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
);
initial begin
// Initialize Inputs
aclk = 0;
s_axis_config_tvalid = 0;
s_axis_config_tdata = 0;
s_axis_data_tvalid = 0;
s_axis_data_tdata = 0;
s_axis_data_tlast = 0;
m_axis_data_tready = 0;
// Wait 100 ns for global reset to finish
#150;
m_axis_data_tready = 1;
s_axis_config_tvalid = 1;
//s_axis_config_tdata = 16'b0101100101011011; // FFT desired (and not IFFT
s_axis_config_tdata = 8'b00000011; // FFT desired (and not IFFT
//s_axis_data_tlast = 1;
s_axis_data_tdata = 32'h0000;
s_axis_data_tvalid = 0;
begin
for(i=0;i<8;i=i+1)
begin
#10
s_axis_data_tvalid <= 1;
s_axis_data_tdata <= {{16'h00},mem0_re[i]};
$display("mem_a[%d] = %h", i, mem0_re[i]);
// if(i== 256)
// s_axis_data_tlast <= 1;
// else
// s_axis_data_tlast <= 0;
end
end
#10;
s_axis_data_tdata = 32'h0000;
s_axis_data_tvalid = 0;
#1000 $finish;
//$stop
end
endmodule
配置示例2:(浮数)
注意:
该浮数遵循IEEE 754 32位单精度规则!!!!
配置过程:
将其Implementstion选项中data format类型选择为floating point类型,其他可不做变更。
由于输入的数据长度为64为,需修改其测试代码为:
module fft_test_bench(
);
reg aclk;
reg s_axis_config_tvalid;
reg s_axis_data_tvalid;
reg s_axis_data_tlast;
reg m_axis_data_tready;
reg [7:0] s_axis_config_tdata;
reg [63: 0] s_axis_data_tdata;
// Outputs
wire s_axis_config_tready;
wire s_axis_data_tready;
wire m_axis_data_tvalid;
wire m_axis_data_tlast;
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;
wire [63 : 0] m_axis_data_tdata;
reg[31:0] mem0_re[0:7];
// reg[32:0] mem1_re[0:7];
// reg[32:0] mem2_re[0:7];
initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus0_32bit.dat",mem0_re);
// initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus1_32bit.dat",mem1_re);
// initial $readmemh("E:/FPGA/ip_test/fft_test_2/stimulus2_32bit.dat",mem2_re);
// reg[7:0] op_sample= 0;
// reg op_sample_first = 1;
// reg[7:0] ip_frame=0;
// reg[7:0] op_frame=0;
integer i;
// generate clk
always #5 aclk =! aclk;
// Instantiate the Unit Under Test (UUT)
xfft_0 uut (
.aclk(aclk), // input wire aclk
.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(s_axis_data_tdata), // input wire [15 : 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(m_axis_data_tready), // 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
);
initial begin
// Initialize Inputs
aclk = 0;
s_axis_config_tvalid = 0;
s_axis_config_tdata = 0;
s_axis_data_tvalid = 0;
s_axis_data_tdata = 0;
s_axis_data_tlast = 0;
m_axis_data_tready = 0;
// Wait 100 ns for global reset to finish
#150;
m_axis_data_tready = 1;
s_axis_config_tvalid = 1;
//s_axis_config_tdata = 16'b0101100101011011; // FFT desired (and not IFFT
s_axis_config_tdata = 8'b00000011; // FFT desired (and not IFFT
//s_axis_data_tlast = 1;
s_axis_data_tdata = 64'h0000;
s_axis_data_tvalid = 0;
begin
for(i=0;i<8;i=i+1)
begin
#10
s_axis_data_tvalid <= 1;
s_axis_data_tdata <= {{32'h00},mem0_re[i]};
$display("mem_a[%d] = %h", i, mem0_re[i]);
// if(i== 256)
// s_axis_data_tlast <= 1;
// else
// s_axis_data_tlast <= 0;
end
end
#10;
s_axis_data_tdata = 64'h0000;
s_axis_data_tvalid = 0;
#1000 $finish;
//$stop
end
endmodule
运行仿真后就可完成测试。测试结果为:
将得到的数据结果进行转换后与matlab计算出的结果进行对比 ,精度极高!!!!
————————————————————————–
延时对比:
一、读取数据
——定点:——
——浮数——
时间均在170ns读取数据!
二、输出数据
——定点——
——浮数——
从图中可以观看到定点处理在705ns时开始输出数据,浮数处理在1005ns时开始输出数据,存在300ns的延时,可能随着具体ZYNQ的频率延时发生改变!!!