我们采用system verilog实现一个8点的基于蝶形运算单元的FFT变换,如下图,是蝶形运算单元的示意图。
然后,由于FFT涉及复数运算,因此,我们编写如下复数类型以及运算符的一个包:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/07/22 11:57:16
// Design Name:
// Module Name: complex_type
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
package complex_type;
parameter DATA_WIDTH = 32;
//复数结构体类型
typedef struct {
logic signed [DATA_WIDTH-1:0] r;
logic signed [DATA_WIDTH-1:0] i;
} Complex;
//复数运算函数
//定义复数乘法
function Complex complex_mul(Complex a,Complex b); //(a.r+i*a.i)x(b.r+i*b.i)
Complex res;
//为防止溢出,扩展到64位再进行乘法
logic [2*DATA_WIDTH-1:0] expand_a_r;
logic [2*DATA_WIDTH-1:0] expand_a_i;
logic [2*DATA_WIDTH-1:0] expand_b_r;
logic [2*DATA_WIDTH-1:0] expand_b_i;
// $display("a=(%d,%d),b=(%d,%d)",a.r,a.i,b.r,b.i);
expand_a_r={{32{a.r[31]}},a.r};
expand_a_i={{32{a.i[31]}},a.i};
expand_b_r={{32{b.r[31]}},b.r};
expand_b_i={{32{b.i[31]}},b.i};
res.r=(expand_a_r*expand_b_r-expand_a_i*expand_b_i)>>>16;
res.i=(expand_a_r*expand_b_i+expand_a_i*expand_b_r)>>>16;
// $display("res=(%d,%d)",res.r,res.i);
return res;
endfunction
//定义复数加法
function Complex complex_add(Complex a,Complex b);
Complex res;
res.r=a.r+b.r;
res.i=a.i+b.i;
return res;
endfunction
//定义复数减法
function Complex complex_sub(Complex a,Complex b);
Complex res;
res.r=a.r-b.r;
res.i=a.i-b.i;
return res;
endfunction
endpackage
然后是我们的FFT模块:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/07/22 09:50:53
// Design Name:
// Module Name: FFT
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
import complex_type::* ;
module FFT
#(parameter DATA_WIDTH = 32,
parameter N = 8,
parameter STAGE = 3)
(
input logic clk,
input logic rst,
input logic valid,
input Complex data_in [0:N-1],
output Complex data_out [0:N-1],
output logic ready
);
logic valid_ff1;
logic valid_ff2;
logic valid_ff3;
//定义旋转因子常量
Complex WN0 = '{65536,0};
Complex WN1 = '{46340,-46340};
Complex WN2 = '{0,-65535};
Complex WN3 = '{-46340,-46341};
//中间结果
Complex tmp [0:STAGE][0:N-1]; //STAGE=log2(N),为蝶形运算单元的级数
//蝶形运算
//第1级 tmp[0]-->tmp[1]
always_ff@(posedge clk) //第一级,蝶形单元跨度为1=2^0
for(int i=0;i>>16);
end
//第2级 tmp[1]-->tmp[2]
always_ff@(posedge clk)
for(int i=0;i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?