基-2 16点fft的verilog实现

本文是采用输入8位数据,输出8位数据的16点fft实现,旋转因子采用8位rom存储,分为cos和sin2个rom存储;输入数据以及每一级的输出数据采用8位的ram进行存储,分为实部和虚部进行存储。采用顺序输入,那么输出则为倒序。

生成rom,可先在matlab中,计算出cos和sin的值,然后写入coe文件,再由ip核生成,具体过程自行百度,懒得百度的话,可以发我的邮箱来获得具体的程序。因为本文采用的16点的fft,点数比较少,所以自己动动手就可以写一个rom了,就可以不用上面的步骤。

生成ram,使用ip核生成与生成rom的过程类似,也是要先获取coe文件,来初始化ram。当然,本文点数比较少,又偷懒了,自己写了一个小ram,初始化ram的值即为输入数据的值。读写分离,即只能读或者只能写。

乘法器单元,采用8x8的带符号的四个乘法器,分别计算real*cos,real*sin,imag*cos,imag*sin。当然这个用ip核生成,自己写的话,是比较麻烦的。

接下来就是控制单元,使用状态机来实现,分为11个状态(s0-s10),其中s0-s9来完成一次蝶形单元的计算,s10为停止状态。当然就可以计算出总共的时间为T*10*8*4(T为时钟周期)。

s0状态:初始化,

s1状态:计算rom的地址,

s2状态: 读rom,将cos和sin值送至乘法器,并计算ram的读取地址

s3状态:读ram,并将读ram地址赋值给写ram地址

s4状态:等待乘法器输出,

s5状态:存储乘法器输出,

s6,s7状态:计算蝶形运算

s8,s9状态:分别写入ram,并且在s9状态进行判断,下一步是继续进行本级蝶形运算还是下一级蝶形运算或是计算结束,转为停止状态。

s10状态:停止状态。

接下来是计算结果,

输入数据为50-65,在out_en为高时,输出结果倒序,序号分别为0-8,1-9,...7-15,结果为57,-3,0,0,0,0,-1,-1-j1,0,0,-1,-1,0,0,0,0,由于每一级蝶形运算的结果都会除以2,因此最后的结果应乘以2^4,通过与matlab计算出的结果进行比对,误差在可接受的范围内。

对于误差的考虑,由于每一级蝶形运算都会进行截尾处理,每一级的误差都会进行累积,因此,你懂的,某些结果的误差可能会很大,如果当某一级产生了溢出,那么会对后面的结果产生很大的影响。因此,目前的想法改进是,输入虽然为8位,但是每一级运算采用8+4+1=13位进行运算,然后在最后一位输出,再进行截尾处理,误差会比较小。

目前ip核已经有了fft模块,因此,在以后的运算中,直接调用ip核来实现,在误差,和速度方面都比较好。下一篇将会对ip核fft进行测试使用

具体请参考胡广书的数字信号处理fft章节,进行学习,再来考虑编程会好一点。

你可能感兴趣的:(基-2 16点fft的verilog实现)