Chinaunix首页 | 论坛 | 博客
  • 博客访问: 44026
  • 博文数量: 18
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2015-01-08 10:21
文章分类
文章存档

2016年(1)

2015年(17)

我的朋友

分类: Verilog

2015-01-08 14:59:26

原文地址:基-2:16位8点FFT verilog 作者:super_sugar

16位八点 FFT 的设计:(暂时不设计成 流水线模式)
原理处理器的设计:输入 X和 Y,旋转因子为 W = C - jS,另输出为 X2 和 Y2 则蝶形运算后输出为:
    X1 = Xr + jXi        Y1 = Yr + jYi            W = C - jS
另输出为 X2    Y2    ,则
    X2 = X1 + WY1 = Xr + YrC + YiS + j(Xi + YiC -YrS);                        [1]
    Y2 = X1 - WY1  = Xr - YrC  -  YiS + j(Xi - YiC + YrS);                       [2]
可以看出蝶形单元需要 乘法器 和 加法器:
所以构建的 Verilog 模型结构如下:
fft_8.v      +/         16位八点 fft
                -/ bufferfly_w80.v    +/       旋转因子是W80    的蝴蝶单元
                                              -/ bufferfly.v    +/             蝴蝶单元
                                                                   -/ control_center.v
                                                                   -/ input_data.v
                                                                   -/ mux4x16_mul_in
                                                                   -/ booth_16bit_multiplier.v
                                                                   -/ mul_data_storage.v
                                                                   -/ mux8x16_add_in.v
                                                                   -/ mux8x1_add_cin.v
                                                                   -/ cla16.v         +/        16位加法器
                                                                                          -/ cla_16.v
                                                                                          -/ cla_8.v
                                                                                          -/ cla_4.v
                                                                                          -/ cla_2.v         +/ 
                                                                                                                 -/ add.v
                                                                                                                 -/ g_p.v
                                                                   -/ output_data.v
                -/ bufferfly_w81.v
                -/ bufferfly_w82.v
                -/ bufferfly_w83.v

下面是功能仿真:代码见附件
首先来设计 乘法器 和 加法器:
             乘法器:选择基于 booth 算法的乘法器     ——        booth_16bit_multiplier.v
             加法器:选择基于先行进位的16位 加法器    ——     cla16.v
booth_16bit_multiplier.v     的 modelsim 仿真结果如下:

              clk:为时钟信号;        CS:为使能信号 0 - 不能计算, 1 - 可以计算;    A和B:分别为输入的数值;
              Done_Sig:为乘法结束信号;    Product:为乘法计算的结果;
功能简介:但 CS 为 1 时,但CLK为上升沿,这进行一步计算,每经过18个周期完成一次乘法运算,完成一次计算 Done_Sig 发出一个脉冲,可以进行下一次计算;

cla16.v                            的 modelsim 仿真结果为:

              a 和 b 为输入数据;       ci:输入进位信号                 s:为输入信号                    co:进位输出信号
功能为:但输入 16 为数据, 相加得出 16 为


有了加法器和乘法器,则可以根据公式 [1] 和 [2],设计蝶形单元
bufferfly.v         +/
                        -/    control_center.v                   // 蝶形单元的时序控制单元
                        -/    input_data.v                        // 输入信号的控制寄存模块
                        -/    mux4x16_mul.v                   // 16位4选一的选择器
                        -/    booth_16bit_multiplier.v       // 基于booth算法的16位乘法器
                        -/    mul_data_storage.v              // 乘法器输出的寄存单元
                        -/    mux8x16_add_in.v               // 16位8选一的选择器
                        -/    mux8x1_add_cin.v               //  1位8选一的选择器
                        -/    cla16.v                                // 先行进位16为加法器
                        -/    output.v                              // 蝶形单元的输出寄存器
整体的设计方案原理图如下:

功能说明安时序,Xr,Xi,Yr, Y分别为输入信号的实部和虚部;接着把数据输入乘法器计算出 YrC,YiS, YrS, YiC;接着把数据输入到加法器
最后得到结果;
下面是蝶形单元的 Modelsim:仿真结果

功能:RST 为使能单元,主要是为了设置初试化一些常量(为了可综合),CS 为使能信号,每一次上升沿可计算一次数据;Xr,Xi,Yr,Yi为输入数据;
通过 matlab 计算可以可知结果是正确的,选择数据时为了保证精度,最好选择大点的数据;

fft_8.v 为16位8点FFT
原理图:

modelsim 仿真图:


功能,X0~X为输入信号,Y0r~Y7i和Y0i~Y7i分别为输出信号的实部和虚部;但RST来个上升沿对内部数据进行初始化,
CS 来一次上升沿进行一次FFT计算, 当计算结束 Done_Sig 为 1; CLK 为每步计算的脉冲。
数据和 matlab 计算的结果进行比对:
数据为:X0 = 1230; X1 = 1420;X2 = 1590;X3 = 1710; X4 = 1940;X5 = 2150;X6 = 2260;X7 = 2380;
matlab仿真进行计算时,注意和 FFT输入的数据关系,( fft 输入为真实计算数据顺序为 0 4 2 6 1 5 3 7)
          matlab 计算 FFT 结果为:
                    Y0 = 14680.0000000000 + 0.00000000000000i
                    Y1 = 
-253.639610306789 + 353.345237791561i
                    Y2 = -650.000000000000 + 550.000000000000i
                    Y3 = -126.360389693211 + 113.345237791561i

               Y4 = -2780.00000000000 + 0.00000000000000i
               Y5 = -126.360389693211 - 113.345237791561i
                    Y6 = -650.000000000000 - 550.000000000000i
                    Y7 = -253.639610306789 - 353.345237791561i
matlab计算的结果和 modelsim 上计算结果进行对比,存在一定误差;
            误差分析:

                     (1)旋转因子的进行量化时带来误差;
                     (2)从乘法器计算出的结果为32位,这里为了和加法器输入位数进行匹配,进行截断
            解决方法:
                     (1)提高数据量化的位数
                     (2)把加法器设计成32位,最后输出时截断;
                     (3)合理选择数据,不能太小,这样能有效的减小误差;


Verilog 代码:  访问密码 9f07







阅读(1588) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~