以下为通信时FFT/IFFT的使用方法简单说明,为定点且带有截位处理。
一、参考说明:
C-model说明:http://xilinx.eetrend.com/content/2021/100062902.html
C-model使用放法:https://blog.csdn.net/zhangningning1996/article/details/106517122
缩放因子:https://www.cnblogs.com/tanqiqi/p/11359321.html
二、配置说明:
第一页配置信息:
1、transform lenfgth : FFT变换长度,如果选择了最下面的‘run time configurable transdorm legth’,则该参数是FFT变化的最大长度,其FFT长度在使用时可通过s_axis_config_tvalid中NFFT字段变化长度,具体的配置信息在官方文件中有说明。这里我们通常使用的是长度不变的FFT,即‘run time configurable transdorm legth未勾选。
2、architecure choice :FFT变换结构,项目中一般使用并行流水线结构pipelined streaming,其结构变换处理时间最短,资源消耗最大。
第二配置页:
主要是数据宽度,格式,控制信号,输出方式,和可选的控制信号。需要注意的是输入的数据是自然方式(Natural Order),输出可以是自然方式也可以是倒序方式(Reversed Order),如果选用倒序方式输出(在m_axis_data_tuser中的xk_index字段,其位宽与变换点数有关,通常为低位,如图:),在后面处理中就要注意这一特性。
1、data format:定点、浮点。在项目中通常采用定点
2、scaling optios :
block floating point :不管输入的格式如何,FFT变化内部都采用浮点,会根据每一级的的数据情况自动缩放,使数据不出现溢出的情况。
scaled :在FPGA中我们项目通常采用scaled,舍入方式均可。在m_axis_data_tuser中会有5Bit表示每一级的缩放情况,在s_axis_config_data中会有相应的字段配置配置缩放因子InData_scale_sch。每一级别包含2个stage,2个bit 表示一级缩放,一般0-3可选,如果log(NFFT)不是2的倍数,则最高一级的缩放只能在0-1之间选取。
unscaled :不用担心变化过程中会出现溢出,但是输入是32bit的话,输出是64bit。
3、output odering options: 输出顺序选项:
nature order:就是FFT变化后的输出已经调整了顺序,按照xk_index自然顺序列出变化结果。
bit/digital reserved oder就是按照变化后的顺序直接输出,是倒序输出,需要自己后续处理,
cyclic perfix insertion :循环前缀插入,一般添加,在进行IFFT后可以根据s_axis_config_data中的CP长度配置自动添加CP。(没用过,想来在OFDM发段进行IFFT后能用到)
4、optional output fileds :选项输出字段:
xk_index:FFT 变幻的结果索引,在m_axis_data_user中有相应的字段。
OVFLO是变换中溢出的指示信号,对应event_fft_overflow.
配置完成后可在下图页面看端口的位宽以及延迟
三、端口说明
端口 |
说明 |
aclk |
输入时钟 |
aclken |
时钟使能 |
aresetn |
复位使能,至少保持两个时钟的低电平才有效 |
s_axis_config_tvalid |
输入配置信息有效(高电平) |
s_axis_config_tready |
s_axis_config_tvalid拉高两个时钟周期后,该口给1输出; |
s_axis_config_tdata |
配置信息,包括FFT/IFFT设置,缩放因子设置,FFT长度设置、循环前缀长度 |
s_axis_data_tvalid |
输入数据有效 |
s_axis_data_tready |
s_axis_config_tvalid拉高两个时钟周期后,该口给1输出,ip核初始化完成,可进行数据输入进行FFT变化;必须等2个时钟 |
s_axis_data_tdata |
输入数据,高位为虚部,低位为实部。默认有符号数 |
s_axis_data_tlast |
输入进行FFT点数长的数据后拉高,停止数据输入 |
m_axis_data_tvalid |
输出数据有效 |
m_axis_data_tready |
输入准备接收FFT输出数据 |
m_axis_data_tdata |
输出数据,高位为实部,低位为虚部 |
m_axis_data_tuser |
输出fft的地址值,输出值*fs/N为对应频点,最高位溢出状态 |
m_axis_data_tlast |
输出数据最后一位标志位 |
m_axis_status_tvalid |
输出状态信息有效位 |
m_axis_status_tready |
输入准备接收状态信息 |
m_axis_status_tdata |
包括块指数(帧开始时发送)、溢出状态(帧结束时发送)。两者不可同时配置 |
event_frame_started |
当帧开始处理时输出高位,持续一个时钟 |
event_tlast_unexpected |
当输入数据不是最后一位,但s_axis_data_tlast为高时,实际输入点数低于配置点数。持续一个时钟 |
event_tlast_missing |
当输入数据应是最后一位,但s_axis_data_tlast为低时,实际输入点数高于配置点数。持续一个时钟 |
event_fft_overflow |
当变换结果溢出时,持续每个时钟,仅当使用了缩放算法时才有此端口 |
event_status_channel_halt |
当ip核需要输出状态信息时,输出缓冲器却满了的时候,此时ip核的所有活动都会停止直到缓冲器空间有空余 |
event_data_in_channel_halt |
当ip核需要输入数据,输入通道却没有数据时,持续每个时钟 |
event_data_out_channel_halt |
当ip需要输出数据,输出缓冲器却满了的时候,此时ip核的所有活动都会停止直到缓冲器空间有空余 |
通常event_tlast_unexpected、event_tlast_missing同时报错,改正m_axis_data_tlast可消除
1、S口通常为输入端(输入数据、输入有效、输入最后一个数据有效、配置信息、配置有效),M口为输出端(输出变换数据、输出有效、输出最后一个数据有效、频点对应地址),event为事件端(帧开始、输入输出通道是否通畅、是否溢出、是否最后一个输入数据有效未对应上)
2、s_axis_config_tdata:
PAD:补零,该数据是以一个字节8bit呈现,当数据不足8bit时要求补零。
SCALE_SCH:
位宽:其实不用你去计算,在配置页面Implementation Details里面会有说明:
Pipelined Streaming I/O and Radix-4 Burst I/O architectures:2ceil(NFFT/2)bit
Radix-2, Burst I/O and Radix-2 Lite Burst I/O architectures:2*NFFT bit
其中NFFT=log2(maximum point size)
缩减因子,仅当使用了缩减算法的时候才需要配置,即在scaling optios选择scaled,
通常,该缩放因子在matlab定点仿真程序中已经确定好了具体位数,此时只需仿真好具体每级缩放多少位
最好结合C-Model用matlab跑几次,以便确定缩放因子以满足要求:不至于溢出,但又不至于输出很小
FWD/INV:1bit。1时是FFT变换,0时是IFFT变换
CP_LEN:log2(maximum point size) bit。仅在Output Ordering Options配置中选择了Cyclic Prefix Insertion时才需要配置
NFFT:5bit。配置变换点数,此时配置页的点数为最大点数,仅在选择了Run Time Configurable Transform Length后才需要配置
2、m_axis_data_tuser:
XK_INDEX:log2(maximum point size) bit,其为输出结果对应频点的指数,如为自然顺序,其结果为0到point size
OVFLO:1bit,其指示当前帧是否溢出,在下一帧到来时,其自动重置。
3、aresetn
在最初最好将其复位,持续2个低电平时钟以上
四、C-Model
先按https://blog.csdn.net/zhangningning1996/article/details/106517122使用方法在matlab中编译函数,下文中为注意事项:
1、C-Model中的参数应与实际在vivado中配置一致,但要注意几点:
(1)、generics.C_INPUT_WIDTH应比你在vivado配置数据宽度多1位,若vivado中是16位,这里应设置为17
(2)、C-Model中输入只能在-1和1之间,在应用中可将输入除以2^n,其中n为FPGA中的位宽所表示的有符号数,在计算完成后再乘以2^n。此时应注意这里n为vivado的宽度,此例中为n=16
(3)、quantize函数中的第四点,应设为[generics.C_INPUT_WIDTH,generics.C_INPUT_WIDTH-1]
2、输入需用quantize函数量化:通常使用以下语句
打开quantize函数的帮助
(1)数据类型这里我们是fixed
(2)截位方式,我们是fix
(3)这里选saturate
(4)这里设置为[宽度,宽度-1]
综上这里的函数应该为
q= quantizer( 'mode','fixed','roundmod', 'fix','overflowmode','saturate','format',[generics.C_INPUT_WIDTH,generics.C_INPUT_WIDTH-1]);
3、通过不断设置缩放因子来测试哪一个缩放因子使得输出不大不小且无溢出。
4、缩放因子在matlab中低位为最高一级,而在vivado中高位为最高一级,即在matlab通过测试得到合适的scaling_sch,在写入vivado的时候要反向
以上C-Model中每一步都要对应,实测不对应时得到的数据与vivado仿真所得数据不一致(也有可能是我做错了),对应时即可得到完全一致的数据
5、下图为最终仿真结果局部对应图:
6、配置截图: